javascript - 为什么在这种情况下我会收到未处理的 promise 拒绝?

标签 javascript node.js asynchronous promise async-await

我的代码中的下一个函数可能由于多种原因而中断执行:

const getAndCheckItem = async (itemId) => {
    try {
        const item = await getItem(itemId);
        if(item.firstFail) {
            throw "First fail";
        }
        if(item.secondFail) {
            throw "Second fail";
        }
        if(notGood(item)) {
            throw "Third fail"; 
        }

        return item;
    }
    catch(err) {
        return Promise.reject(err);
    }
};

如果我按以下方式在其他异步函数中调用它,则一切都很好并且可以处理任何内部抛出:

try {
    item = await getAndCheckItem(ids[0]);
}
catch(err) {
    // handle error
}

但是,当我为多个 id 调用该函数时:

try {
    items = await Promise.all([ids.map(value => getAndCheckItem(value))]);
}
catch(err) {
    // handle error
}

如果发生任何内部抛出,我会收到未处理的 promise 拒绝。我了解 Promise.all() 将任何返回的非 promise 值视为已解决的 promise 。然而,Promise.reject(err) 应该返回一个 Promise 并因此被处理。有什么问题吗?

最佳答案

Promise.all() considers any returned non-promise value as a resolved promise.

当然,但是当你这样做时

return Promise.reject(err);

您要返回一个 Promise,因此一旦调用者将其解开,getAndCheckItem 调用就会导致 Promise 被拒绝。执行 return Promise.reject(err) 与在 async 中执行 throw err 非常相似。

如果您在catch中所做的只是重新抛出或返回被拒绝的Promise,那么没有多大意义 - 您也可以完全保留该部分,而让调用者处理它:

const getAndCheckItem = async (itemId) => {
  const item = await getItem(itemId);
  if(item.firstFail) {
    throw "First fail";
  }
  if(item.secondFail) {
    throw "Second fail";
  }
  if(notGood(item)) {
    throw "Third fail"; 
  }
  return item;
}

您当前还将 Promise 的数组传递给 Promise.all:

await Promise.all([ids.map(value => getAndCheckItem(value))]);

在这种情况下,Promise.all 不会真正执行任何操作,因为其数组中唯一的项是非 Promise(另一个数组)。如果任何内部 promise 被拒绝,它们将不会被处理,所以你会得到一个未处理的拒绝。

相反,将 Promise 数组传递给 Promise.all:

await Promise.all(ids.map(value => getAndCheckItem(value)));

或者,更简洁地说:

await Promise.all(ids.map(getAndCheckItem));

关于javascript - 为什么在这种情况下我会收到未处理的 promise 拒绝?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59745874/

相关文章:

javascript - 将窗口滚动到元素的底部

javascript - Jquery滚动到不滚动

javascript - token '==' 是意外的 ngClass

c - 管道没有被子进程读取?

javascript - 使用 Multer 上传多个文件

javascript - javascript 对象和 json 数据等效吗?

node.js - 在 Meteor 中上传图片,上传空文件

c# - 在我想要等待的方法上获得 Cannot await void

c++ - 使用 BOOST_ASIO_DISABLE_IOCP 有什么缺点?

javascript - 为什么我在 JavaScript 的控制台中得到 undefined