为了学习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
是什么,何时出现以及我必须检查以消除此警告?
答案 0 :(得分:146)
这个错误的根源在于,每个承诺都应该处理承诺拒绝,即拥有 .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");
});
在某些情况下,即使我们为promises编写了.catch(..),也会出现 “未处理的拒绝承诺” 消息。这都是关于你如何编写代码的。即使我们正在处理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(...)
作为链处理,而是作为单独处理。出于某种原因,JavaScript引擎将其视为承诺而没有未处理的承诺拒绝。
答案 1 :(得分:30)
这是Promise
与.reject()
一起完成或async
已执行代码中引发异常且没有.catch()
处理拒绝的情况。
被拒绝的承诺就像是一个异常,它向应用程序入口点冒泡并导致根错误处理程序产生该输出。
另见
答案 2 :(得分:19)
承诺在被拒绝后可以“处理”。也就是说,在提供catch处理程序之前,可以调用promise的拒绝回调。这种行为对我来说有点麻烦,因为人们可以写......
var promise = new Promise(function(resolve) {
kjjdjf(); // this function does not exist });
...在这种情况下,Promise会被默默拒绝。如果忘记添加一个catch处理程序,代码将继续静默运行而不会出现错误。这可能导致挥之不去且难以发现的错误。
在Node.js的案例中,有人谈到处理这些未处理的Promise拒绝并报告问题。这让我想到ES7 async / await。考虑这个例子:
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;
}
在上面的例子中,假设在满足getRoomTemperature之前,牙齿掉牙被拒绝(错误:没有牙膏!)。在这种情况下,在等待teethPromise之前,将会有未处理的Promise拒绝。
我的观点是......如果我们认为未处理的Promise拒绝是一个问题,稍后由await处理的Prom可能会无意中被报告为错误。然后,如果我们认为未处理的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而没有捕获,并在稍后添加一个,大多数“未处理的拒绝错误”实现实际上将在我稍后处理它时收回警告。换句话说,async / await不会以任何我能看到的方式改变“未处理的拒绝”讨论。
要避免这个陷阱,请以这种方式编写代码:
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);
}
请注意,这可以防止任何未处理的承诺拒绝。
答案 3 :(得分:9)
"弃用警告:未处理拒绝承诺拒绝"
TLDR:承诺有resolve
和reject
,执行reject
没有捕获来处理它已被弃用,因此您必须至少拥有catch
在顶层。
答案 4 :(得分:1)
我遇到了与 NodeJS 类似的问题,其中的罪魁祸首是forEach循环。请注意,forEach是一个同步功能(非异步)。因此,它只是忽略了返回的承诺。 解决方案是使用for-of循环: 我收到错误的代码:
UnhandledPromiseRejectionWarning:未处理的承诺拒绝。该错误是由于在没有catch块的情况下抛出异步函数而产生的,或者是由于拒绝了未使用.catch()处理的诺言而产生的
如下:
permissionOrders.forEach( async(order) => {
const requestPermissionOrder = new RequestPermissionOrderSchema({
item: order.item,
item_desc: order.item_desc,
quantity: order.quantity,
unit_price: order.unit_price,
total_cost: order.total_cost,
status: order.status,
priority: order.priority,
directOrder: order.directOrder
});
try {
const dat_order = await requestPermissionOrder.save();
res.json(dat_order);
} catch(err){
res.json({ message : err});
}
});
上述问题的解决方案如下:
for (let order of permissionOrders){
const requestPermissionOrder = new RequestPermissionOrderSchema({
item: order.item,
item_desc: order.item_desc,
quantity: order.quantity,
unit_price: order.unit_price,
total_cost: order.total_cost,
status: order.status,
priority: order.priority,
directOrder: order.directOrder
});
try {
const dat_order = await requestPermissionOrder.save();
res.json(dat_order);
} catch(err){
res.json({ message : err});
}
};
答案 5 :(得分:1)
在将数据发送到数据库之前,请尝试不关闭连接。从您的代码中删除client.close();
,它将正常工作。
答案 6 :(得分:0)
当我实例化一个Promise时,我将生成一个异步函数。如果函数运行良好,则调用RESOLVE,然后流程在THEN的RESOLVE处理程序中继续。如果该函数失败,则通过调用REJECT终止该函数,然后流程在CATCH中继续。
在不赞成使用NodeJ的拒绝处理程序中。您的错误只是一个警告,我在node.js github中读取了它。我找到了。
DEP0018:未处理的承诺拒绝
类型:运行时
已弃用未处理的承诺拒绝。将来,未处理的承诺拒绝将以非零退出代码终止Node.js进程。
答案 7 :(得分:0)
在我的情况下,Promise不会拒绝也不会解决,因为Promise函数引发了异常。此错误会导致UnhandledPromiseRejectionWarning消息。