2016-11-09 164 views
87

为了学习Angular 2,我正在尝试他们的教程。什么是未处理的承诺拒绝?

我得到这样的错误:

(node:4796) UnhandledPromiseRejectionWarning: Unhandled promise rejection (r                          ejection id: 1): Error: spawn cmd ENOENT 
[1] (node:4796) DeprecationWarning: Unhandled promise rejections are deprecated. 
In the future, promise rejections that are not handled will terminate the Node. 
js process with a non-zero exit code. 

我通过不同的问题和答案进去SO,但无法找到一个“未处理的承诺拒绝”是什么。

任何人都可以简单地解释我是什么,也是什么Error: spawn cmd ENOENT是什么时候出现以及我必须检查以摆脱此警告?

回答

23

这是当一个Promise完成于.reject()或例外是在异步抛出执行的代码并没有.catch()做处理拒绝。

被拒绝的承诺就像是一个异常,它向应用程序入口点冒泡并导致根错误处理程序产生该输出。 https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/reject - - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise -

也 见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch

+0

哪里可以更改?我使用离子3时,我打离子cordova构建andorid命令给我这个错误。 –

+0

很难说这个信息。我建议你尽量创造一个最小的复制品,并为你的具体情况创建一个新的问题。 –

+0

我已经打开了它的赏金。请看看它https://stackoverflow.com/q/48145380/5383669 –

99

这个错误的根源在于一个事实,即每一个承诺,预计处理答应拒绝即有.catch(... )。您可以通过将.catch(...)添加到以下代码中的承诺中来避免相同情况。

例如,函数PTEST()要么基于全局变量somevar

var somevar = false; 
var PTest = function() { 
    return new Promise(function (resolve, reject) { 
     if (somevar === true) 
      resolve(); 
     else 
      reject(); 
    }); 
} 
var myfunc = PTest(); 
myfunc.then(function() { 
    console.log("Promise Resolved"); 
}).catch(function() { 
    console.log("Promise Rejected"); 
}); 

在一些情况下的值来解决或拒绝一个承诺,则“未处理的承诺排斥“即使我们有.catch(..)写的承诺信息。它关于你如何编写你的代码。下面的代码将产生“未处理的承诺拒绝”即使我们正在处理捕获

var somevar = false; 
var PTest = function() { 
    return new Promise(function (resolve, reject) { 
    if (somevar === true) 
     resolve(); 
    else 
     reject(); 
}); 
} 
var myfunc = PTest(); 
myfunc.then(function() { 
    console.log("Promise Resolved"); 
}); 
// See the Difference here 
myfunc.catch(function() { 
    console.log("Promise Rejected"); 
}); 

不同的是,你不处理.catch(...)为链,但作为独立。出于某种原因,Java脚本引擎将其视为承诺而没有未处理的承诺拒绝

+1

它似乎工作,如果你在第二个例子中添加'myFunc = myFunct.then ...'。 – einstein

+0

@einstein它会出现工作,因为您正在重新创建与第一个示例中相同的链:'var x = foo(); x = x.then(...); x = x.catch(...)' – randomsock

+3

@einstein在你的非连锁示例中,当你说“由于某种原因,Java脚本引擎将它视为承诺而没有未处理的承诺拒绝”,这不是因为和例外可能是抛出在'.then(()=> {...})'你**不是**处理?我不认为这与你将它们链接在一起时是一样的。是吗? –

12

承诺可以在被拒绝后“处理”。也就是说,在提供catch处理程序之前,可以调用promise的拒绝回调函数。这种行为是有点麻烦,因为我可以写...

var promise = new Promise(function(resolve) { 
kjjdjf(); // this function does not exist }); 

......在这种情况下,诺言被拒绝默默。如果忘记添加catch处理程序,代码将继续无提示地运行而没有错误。这可能导致徘徊和难以发现的错误。

在Node.js的情况下,有人谈论处理这些未处理的Promise拒绝并报告问题。这使我到ES7异步/等待。考虑下面这个例子:

async function getReadyForBed() { 
    let teethPromise = brushTeeth(); 
    let tempPromise = getRoomTemperature(); 

    // Change clothes based on room temperature 
    let temp = await tempPromise; 
    // Assume `changeClothes` also returns a Promise 
    if(temp > 20) { 
    await changeClothes("warm"); 
    } else { 
    await changeClothes("cold"); 
    } 

    await teethPromise; 
} 

在上面的例子中,假设teethPromise被拒绝(错误:出牙膏)getRoomTemperature果然应验了。在这种情况下,会有一个未处理的Promise拒绝,直到等待toothPromise。

我的观点是......如果我们认为未处理的Promise拒绝是一个问题,那么稍后由await处理的Promise可能会无意中报告为错误。再次,如果我们认为未处理的Promise拒绝不成问题,合理的错误可能不会被报告。

有关这方面的想法?

这是关系到Node.js的项目发现这里的讨论:

Default Unhandled Rejection Detection Behavior

如果你这样写代码:

function getReadyForBed() { 
    let teethPromise = brushTeeth(); 
    let tempPromise = getRoomTemperature(); 

    // Change clothes based on room temperature 
    return Promise.resolve(tempPromise) 
    .then(temp => { 
     // Assume `changeClothes` also returns a Promise 
     if (temp > 20) { 
     return Promise.resolve(changeClothes("warm")); 
     } else { 
     return Promise.resolve(changeClothes("cold")); 
     } 
    }) 
    .then(teethPromise) 
    .then(Promise.resolve()); // since the async function returns nothing, ensure it's a resolved promise for `undefined`, unless it's previously rejected 
} 

当getReadyForBed被调用时,它会同步创建最终的(未返回的)promise - 与任何其他promise(当然,根据引擎不同,可能没有任何内容)会有相同的“未处理的拒绝”错误。 (我觉得很奇怪你的函数没有返回任何东西,这意味着你的异步函数产生了未定义的承诺。

如果我现在做一个Promise而没有捕获,并且稍后添加一个Promise,大多数“未处理的拒绝错误“实际上,当我稍后处理它时,实际上会收回警告,换句话说,异步/等待不会以任何方式改变”未处理的拒绝“讨论。这样的代码:

async function getReadyForBed() { 
    let teethPromise = brushTeeth(); 
    let tempPromise = getRoomTemperature(); 

    // Change clothes based on room temperature 
    var clothesPromise = tempPromise.then(function(temp) { 
    // Assume `changeClothes` also returns a Promise 
    if(temp > 20) { 
     return changeClothes("warm"); 
    } else { 
     return changeClothes("cold"); 
    } 
    }); 
    /* Note that clothesPromise resolves to the result of `changeClothes` 
    due to Promise "chaining" magic. */ 

    // Combine promises and await them both 
    await Promise.all(teethPromise, clothesPromise); 
} 

请注意,这应该防止任何未处理的承诺拒绝。

1

TLDR:承诺有resolvereject,不允许丢失reject了。 myPromise.then(funcResolve(){}).catch(funcReject(){});

相关问题