NodeJS 在并行块中处理异步函数并忽略单个项目的错误

问题描述 投票:0回答:1

我正在尝试以并行“块”的方式处理 NodeJS (v14) 中的异步函数。我的代码工作正常,除非异步函数 (

processItem()
) 其中一项出错,在这种情况下,整个处理被完全阻止。

const processGroup = async () => {
  const chunks = [
    [0, 1, 2, 3, 4, 5],
    [6, 7, 8, 9, 10, 11],
    // etc.
  ];
  try {
    for (const chunk of chunks) {
      await Promise.all(chunk.map(async id => { await processItem(id) }));
    }
  } catch (e) {
    throw new Error('Error');
  }
}

const processItem = async id => {
  try {
    // run couple of async calls from another library (dependency)
    const itemURL = await itemProcessor.getItem(id);  // this might produce an error
    // ...
    // fetch item details
    const itemDetails = await fetch(itemURL);
  } catch (e) {
    console.log(e);
  }
}

如果ID为

0
的项目在
processItem()
函数中产生错误,似乎没有其他项目被处理,我也没有通过第一个块。在这种情况下,我怎样才能忽略错误的项目并继续处理其余的项目?

编辑
根据建议更新代码以使用

Promise.allSettled

const processGroup = async () => {
  const chunks = [
    [0, 1, 2, 3, 4, 5],
    [6, 7, 8, 9, 10, 11],
    // etc.
  ];
  try {
    for (const chunk of chunks) {
      const results = await Promise.allSettled(chunk.map(id => processItem(id)));
      results.forEach((result, index) => {
        console.log(result, index);
        if (result.status === 'rejected') {
          console.error(`Error processing item with ID ${chunk[index]}: ${result.reason}`);
        }
      });
    }
  } catch (e) {
    throw new Error('Error');
  }
}

const processItem = async id => {
  console.log(id);
  try {
    // run couple of async calls from another library (dependency)
    const itemURL = await itemProcessor.getItem(id);  // this might produce an error
    // ...
    // fetch item details
    console.log(itemURL);
    const itemDetails = await fetch(itemURL);
  } catch (e) {
    console.log(e);
  }
}
node.js asynchronous async-await promise fetch-api
1个回答
1
投票

如果您更新代码以使用

Promise.allSettled()
(而不是
Promise.all()
),则循环不会被任何失败或错误阻塞。然后,您可以选择以您认为最好的方式处理这些情况。

例如

const processGroup = async () => {
  const chunks = [
    [0, 1, 2, 3, 4, 5],
    [6, 7, 8, 9, 10, 11],
    // etc.
  ];
  for (const chunk of chunks) {
    const results = await Promise.allSettled(chunk.map(id => processItem(id)));
    results.forEach((result, index) => {
      if (result.status === 'rejected') {
        console.error(`Error processing item with ID ${chunk[index]}: ${result.reason}`);
      }
    });
  }
};

const processItem = async id => {
  // run couple of async calls from another library (dependency)
  const itemURL = await itemProcessor.getItem(id);  // this might produce an error
  // ...
  // fetch item details
  const itemDetails = await fetch(itemURL);
};
© www.soinside.com 2019 - 2024. All rights reserved.