Javascript 为什么在这种情况下我会遭到未经处理的拒绝?

Javascript 为什么在这种情况下我会遭到未经处理的拒绝?,javascript,node.js,asynchronous,promise,async-await,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 "S

我的代码中有下一个函数,由于以下几个原因可以中断执行:

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.all()将任何返回的非承诺值视为已解决的承诺。但是,
Promise.reject(err)
应该返回一个承诺,并因此得到处理。有什么问题吗

Promise.all()将任何返回的非承诺值视为已解析的承诺

当然,但是当你这样做的时候

return Promise.reject(err);
您正在返回一个承诺,因此,一旦调用者打开了它,调用
getAndCheckItem
将导致拒绝的承诺。执行
return Promise.reject(err)
与执行
throw err
内部操作
async
非常相似

如果您在捕获过程中所做的只是重新抛出或返回一个被拒绝的承诺,那么这没有多大意义-您不妨完全忽略这一部分,让调用方处理它:

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。所有

await Promise.all([ids.map(value => getAndCheckItem(value))]);
await Promise.all(ids.map(value => getAndCheckItem(value)));
在这种情况下,
Promise.all
实际上不会做任何事情,因为其数组中唯一的项是非Promise(另一个数组)。如果任何一个内在的承诺被拒绝,它们都不会被处理,所以你会得到一个未经处理的拒绝

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

await Promise.all([ids.map(value => getAndCheckItem(value))]);
await Promise.all(ids.map(value => getAndCheckItem(value)));
或者,更简洁地说:

await Promise.all(ids.map(getAndCheckItem));
Promise.all()将任何返回的非承诺值视为已解析的承诺

当然,但是当你这样做的时候

return Promise.reject(err);
您正在返回一个承诺,因此,一旦调用者打开了它,调用
getAndCheckItem
将导致拒绝的承诺。执行
return Promise.reject(err)
与执行
throw err
内部操作
async
非常相似

如果您在捕获过程中所做的只是重新抛出或返回一个被拒绝的承诺,那么这没有多大意义-您不妨完全忽略这一部分,让调用方处理它:

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。所有

await Promise.all([ids.map(value => getAndCheckItem(value))]);
await Promise.all(ids.map(value => getAndCheckItem(value)));
在这种情况下,
Promise.all
实际上不会做任何事情,因为其数组中唯一的项是非Promise(另一个数组)。如果任何一个内在的承诺被拒绝,它们都不会被处理,所以你会得到一个未经处理的拒绝

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

await Promise.all([ids.map(value => getAndCheckItem(value))]);
await Promise.all(ids.map(value => getAndCheckItem(value)));
或者,更简洁地说:

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

尝试删除
ids.map
上的方括号<代码>映射()
已返回array@CristopherNamchee谢谢你,先生!我花了几个小时来找出错误,阅读文章,改变我对宇宙的理解,但和往常一样,我找错了地方。:)尝试删除
ids.map
上的方括号<代码>映射()
已返回array@CristopherNamchee谢谢你,先生!我花了几个小时来找出错误,阅读文章,改变我对宇宙的理解,但和往常一样,我找错了地方。:)