为什么 JS 中的 try catch 不处理循环内的 Promise 拒绝?

2023-12-03

如果我在 for 中有一个承诺拒绝,但没有被 for 或调用者方法 catch 块周围的 try/catch 捕获

const asyncMethod = async (item) => {
  return Promise.reject(item);
};

const sleep = (ms) => {
  return new Promise((resolve) => setTimeout(resolve, ms));
};

const myMethod = async () => {
  try {
    const myArr = [1, 2,];
    
    const promises = [];

    for (const item of myArr) {
      const myPromise = asyncMethod(item);
      promises.push(myPromise);
      await sleep(1);
    }

    await Promise.allSettled(promises);

  } catch (e) {
    console.log('handled by try catch');
  }
};

myMethod().catch(() => {
  console.log('handled by invoker');
});

如果我运行这个,我会得到未处理的拒绝,我想知道为什么它没有击中我的捕获块。

我不是在寻求解决方案,我只是想了解 V8 是如何工作的。


这不仅仅是V8 -any符合规范的实现将使用此代码产生未处理的拒绝。

在 Promise 被拒绝的那一刻,必须有一个.catch处理程序某处已附加到 Promise 中以捕获拒绝。否则,将发生未处理的拒绝 - 引擎无法展望未来以查看您是否稍后附加处理程序,它必须被视为已附加right当 Promise 被拒绝时。

因为你做

  const myPromise = asyncMethod(item);
  promises.push(myPromise);
  await sleep(1);

你正在等待sleep before将拒绝的承诺传递给.allSettled(这将被视为拒绝处理程序)。如果 Promise 在所有之前拒绝sleep完成后,将会出现未处理的拒绝。

(.allSettled does算作拒绝处理程序,如下所示:)

const asyncMethod = async (item) => {
  return Promise.reject(item);
};

const sleep = (ms) => {
  return new Promise((resolve) => setTimeout(resolve, ms));
};

const myMethod = async () => {
  try {
    const myArr = [1, 2,];
    
    const promises = [];

    for (const item of myArr) {
      const myPromise = asyncMethod(item);
      promises.push(myPromise);
      // dummy rejection handler through .allSettled attached immediately, just to illustrate:
      Promise.allSettled([myPromise]);
      await sleep(1);
    }

    await Promise.allSettled(promises);

  } catch (e) {
    console.log('handled by try catch');
  }
};

myMethod().catch(() => {
  console.log('handled by invoker');
});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 JS 中的 try catch 不处理循环内的 Promise 拒绝? 的相关文章

随机推荐