我正在循环中处理一个列表,该循环运行async返回一个promise而我不想退出处理异常,所以我聚合它们并将它们传递给外部finally块中的resolve回调。 我想知道这是否是反模式,如果是,请提供一个如何正确执行的指针。 感谢。
实施例
async doSomething(list) {
let errorCount = 0
let errors = []
return new Promise(async (resolve, reject) => {
try {
list.forEach(async (item) => {
try {
actionThatThrows(item)
} catch (e) {
errorCount++
errors[errorCount] = e
}
})
} catch (e) {
errorCount++
errors[errorCount] = e
} finally {
if (errorCount > 0) {
resolve(errors)
} else {
resolve()
}
}
})
}
答案 0 :(得分:8)
是的,此代码使用了几个反模式:
async function
to a Promise
constructor Promise
constructor when you already have promises around forEach
does not work with async function
s 我不想退出处理异常但聚合它们
您可能需要查看Wait until all ES6 promises complete, even rejected promises。
但是假设你想要连续迭代,你可以在没有这些的情况下做到这一点:
async function doSomething(list) {
const errors = [];
for (let item of list) {
try {
await actionThatThrows(item);
} catch (e) {
errors.push(e);
}
}
if (errors.length)
return errors;
else
return …;
}
答案 1 :(得分:3)
错误是异步计算的结果,因此全局看起来是合法的。
假设actionThatThrows
返回一个承诺(在你的问题和代码中不清楚),它看起来像是这样写的:
function doSomething(list) {
let errors = []
return Promise.all(list.map(
item => actionThatThrows(item).catch(e => {
errors.push(e);
})
)).then(()=>{
return errors.length ? errors : undefined;
});
}
答案 2 :(得分:0)
1)async doSomething没有调用await,所以删除异步 2)list.forEach中的异步不是调用await,所以删除异步 3)第一次捕获将捕获所有。第二次捕获将永远不会被击中,因此删除第二次捕获并最终
代码可以简化为:
doSomething(list) {
let errorCount = 0,
errors = [];
for (let item of list) {
try {
actionThatThrows(item); //I suppose this is not returning a promise
} catch (e) {
errorCount += 1;
errors[errorCount] = e;
}
}
if (errorCount > 0) {
return errors; //return Promise.reject(errors);
} else {
//return Promise.resolve();
}
}