通过使用节点js12.16.1 LTS,我不明白为什么这段代码会导致双拒绝(一个未处理,另一个被捕获)。当我删除的p承诺并在create_bug()中等待p时,它工作得很好(只有一个尝试捕获块捕捉到一个拒绝)。我搞不懂为什么。
Nodejs专家,你能帮忙吗?
'use strict';
process.on('uncaughtException', (err) => {
console.error(`uncaughtException: ${JSON.stringify({name: err.name, msg: err.message})}`);
});
process.on('unhandledRejection', (err) => {
console.error(`unhandledRejection: ${JSON.stringify({name: err.name, msg: err.message})}`);
});
async function create_bug() {
console.log('In create');
let res = superCreate();
console.log(`In create, res = ${res}`);
let p = new Promise((a, r) => setTimeout(() => a(), 0));
await p;
return res;
}
async function superCreate() {
console.log('superCreate : now throwing');
throw new Error("Something wrong");
}
async function create_OK() {
console.log('In create');
let res = await superCreate();
console.log(`In create, res = ${res}`);
let p = new Promise((a, r) => setTimeout(() => a(), 0));
await p;
return res;
}
async function main() {
try {
let res = await create_bug();
console.log(`create result : ${res}`);
} catch (err) {
console.error(`ERROR caught in main : ${JSON.stringify({name: err.name, msg: err.message})}`);
}
}
main().then(() => {
setTimeout(() => console.log(`Finished`), 2000);
});发布于 2020-04-20 21:54:18
变量res中包含的承诺是,而不是等待的,在被拒绝之前,没有附加( catch处理程序)。因此,未处理的承诺拒绝被触发。在main中触发等待时,在拒绝后附加处理程序。
请注意,即使拒绝处理程序是在拒绝后附加在承诺上的,也会调用它。例如:
async function main() {
let res = create_bug();
try {
await res;
console.log(`create result : ${res}`);
} catch (err) {
console.error(`ERROR caught in main : ${JSON.stringify({name: err.name, msg: err.message})}`);
}
res.catch(err => console.error(`main1: ${JSON.stringify({name: err.name, msg: err.message})}`));
res.catch(err => console.error(`main2: ${JSON.stringify({name: err.name, msg: err.message})}`));
}注意,您现在还将得到"main1“和"main2”错误。
或者,尝试从async函数中删除superCreate,现在您应该看到In create, res = ${res}不是打印出来的,而是同步处理的。
另一种选择是直接从create_bug返回res,而无需等待,而是等待res in main。然后,您将看到与原来类似的行为:未处理的拒绝和“正常”的捕获处理块。
async function create_bug() {
console.log('In create');
let res = superCreate();
console.log(`In create, res = ${res}`);
return res;
}
async function superCreate() {
console.log('superCreate : now throwing');
throw new Error("Something wrong");
}
async function main() {
try {
let res = create_bug();
let p = new Promise((a, r) => setTimeout(() => a(), 0));
await p;
await res;
console.log(`create result : ${res}`);
} catch (err) {
console.error(`ERROR caught in main : ${JSON.stringify({name: err.name, msg: err.message})}`);
}
}https://stackoverflow.com/questions/61324284
复制相似问题