0

我模拟了 3 个承诺 - 两个已解决,一个被拒绝,包装了一个 try-catch 函数,但我仍然在控制台中收到警告:(节点:4159)UnhandledPromiseRejectionWarning:未处理的承诺拒绝。

    const emulate = (id, ms) =>
      new Promise((resolve, reject) => {
        if (ms > 1500) reject(id);
        setTimeout(() => {
          resolve(id);
        }, ms);
      });

    const promises = [
      emulate(1, 500),
      emulate(2, 1000),
      emulate(3, 2000)
    ];

    async function stepByStepResolve() {
      try {
        for await (const promise of promises)
          console.log(promise);
      } catch (e) {
        console.log('Err:', e);
      }
    }

    stepByStepResolve();
4

1 回答 1

0

当您调用数组emulate(3, 2000)promises,会创建一个 Promise,并将在事件循环的下一阶段被拒绝,除非您在此之前正在侦听并处理它。现在,在 中for loop,您正在按顺序收听所有 3 个 Promise,并且由于emulate(3, 2000)是最后收听的,因此在您迭代它时它已经被拒绝了。

我可以为此提出两种解决方案:

解决方案 1:只需将emulate(3, 2000)其作为数组中的第一个元素

let promises = [
  emulate(3, 2000),
  emulate(1, 500),
  emulate(2, 1000),
];

这将允许它被倾听,并在它被拒绝之前被捕获。

解决方案 2(这更像是一个建议):使用生成器而不是数组,如下所示:

function* promisesGenerator() {
  yield emulate(3, 2000);
  yield emulate(1, 500);
  yield emulate(2, 1000);
}

async function stepByStepResolve() {
  try {
    for await (const promise of promisesGenerator())
      console.log(promise);
  } catch (e) {
    console.log('Err:', e);
  }
}

stepByStepResolve();

这将防止 promise 在 之前创建for loop,并且会在您遍历生成器时一一创建。

于 2020-06-25T13:05:32.693 回答