Promise 在被拒绝后可以“处理”。也就是说,可以在提供 catch 处理程序之前调用 Promise 的拒绝回调。这种行为对我来说有点麻烦,因为可以写...
var promise = new Promise(function(resolve) {
kjjdjf(); // this function does not exist });
... 在这种情况下,Promise 会被默默地拒绝。如果忘记添加 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;
}
在上面的例子中,假设在 getRoomTemperature 完成之前,toothPromise 被拒绝了(错误:牙膏用完了!)。在这种情况下,将有一个未处理的 Promise 拒绝,直到 await 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 相同的“未处理拒绝”错误(当然,可能什么都没有,取决于引擎)。 (我觉得很奇怪你的函数没有返回任何东西,这意味着你的异步函数产生了一个未定义的承诺。
如果我现在做出一个承诺而没有捕获,然后添加一个,大多数“未处理的拒绝错误”实现实际上会在我稍后处理它时收回警告。换句话说,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);
}
请注意,这应该防止任何未处理的承诺拒绝。