首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Nodejs重复拒绝(未处理的拒绝,并位于try/catch块中)

Nodejs重复拒绝(未处理的拒绝,并位于try/catch块中)
EN

Stack Overflow用户
提问于 2020-04-20 13:58:48
回答 1查看 276关注 0票数 0

通过使用节点js12.16.1 LTS,我不明白为什么这段代码会导致双拒绝(一个未处理,另一个被捕获)。当我删除的p承诺并在create_bug()中等待p时,它工作得很好(只有一个尝试捕获块捕捉到一个拒绝)。我搞不懂为什么。

Nodejs专家,你能帮忙吗?

代码语言:javascript
复制
'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);
});
EN

Stack Overflow用户

回答已采纳

发布于 2020-04-20 21:54:18

变量res中包含的承诺是,而不是等待的,在被拒绝之前,没有附加( catch处理程序)。因此,未处理的承诺拒绝被触发。在main中触发等待时,在拒绝后附加处理程序。

请注意,即使拒绝处理程序是在拒绝后附加在承诺上的,也会调用它。例如:

代码语言:javascript
复制
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。然后,您将看到与原来类似的行为:未处理的拒绝和“正常”的捕获处理块。

代码语言:javascript
复制
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})}`);
  }
}
票数 1
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61324284

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档