gpt4 book ai didi

javascript - 在 forEach 中等待 catch block 失败

转载 作者:行者123 更新时间:2023-11-30 07:31:33 32 4
gpt4 key购买 nike

我有一个类似数组的结构,它公开了异步方法。异步方法调用包含 try-catch block ,这些 block 在捕获错误的情况下会公开更多异步方法。我想了解为什么 forEach 不能很好地与 async/await 配合使用。

let items = ['foo', 'bar', 'baz'];

// Desirable behavior
processForLoop(items);
/* Processing foo
* Resolved foo after 3 seconds.
* Processing bar
* Resolved bar after 3 seconds.
* Processing baz
* Resolved baz after 3 seconds.
*/

// Undesirable behavior
processForEach(items);
/* Processing foo
* Processing bar
* Processing baz
* Resolved foo after 3 seconds.
* Resolved bar after 3 seconds.
* Resolved baz after 3 seconds.
*/

async function processForLoop(items) {
for(let i = 0; i < items.length; i++) {
await tryToProcess(items[i]);
}
}

async function processForEach(items) {
items.forEach(await tryToProcess);
}

async function tryToProcess(item) {
try {
await process(item);
} catch(error) {
await resolveAfter3Seconds(item);
}
}

// Asynchronous method
// Automatic failure for the sake of argument
function process(item) {
console.log(`Processing ${item}`);
return new Promise((resolve, reject) =>
setTimeout(() => reject(Error('process error message')), 1)
);
}

// Asynchrounous method
function resolveAfter3Seconds(x) {
return new Promise(resolve => setTimeout(() => {
console.log(`Resolved ${x} after 3 seconds.`);
resolve(x);
}, 3000));
}

最佳答案

I'd like to understand why forEach doesn't play nicely with async/await.

当我们认为 async 只是返回 promise 的函数的语法糖时,事情就容易多了。

项目。 forEach (f) 需要一个函数 f 作为参数,它在返回之前一次对每个项目执行一次。它忽略 f 的返回值。

items.forEach(await tryToProcess) 相当于 Promise.resolve(tryToProcess).then(ttp => items.forEach(ttp))

并且在功能上与 items.forEach(tryToProcess) 没有区别。

现在 tryToProcess 返回一个 promise ,但是 forEach 忽略了返回值,正如我们提到的,所以它忽略了那个 promise 。这是个坏消息,可能导致未处理的拒绝错误,因为所有 promise 链都应返回或终止 catch 以正确处理错误。

这个错误相当于忘记了await。不幸的是,没有 array.forEachAwait()

项目。 map (f) 稍微好一点,因为它根据 f 的返回值创建了一个数组,在 tryToProcess 的情况下,它会给我们一个 promise 数组。例如。我们可以这样做:

await Promise.all(items.map(tryToProcess));

...但是对每个项目的所有 tryToProcess 调用将彼此并行执行。

重要的是,map 并行运行它们。 Promise.all 只是等待它们完成的一种手段。

通常...

我总是在 async 函数中使用 for of 而不是 forEach:

for (const item of items) {
await tryToProcess(item);
}

...即使循环中没有await,以防万一我稍后添加一个,以避免这种脚枪。

关于javascript - 在 forEach 中等待 catch block 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50594866/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com