1 回答
![?](http://img1.sycdn.imooc.com/5458683f00017bab02200220-100-100.jpg)
TA贡献2019条经验 获得超9个赞
await 当你给它一个数组时并没有做任何特别的事情,它只是将数组包装在一个已解决的承诺中。
要等待承诺解决,请使用Promise.all:
async function callService(idList) {
return await Promise.all(idList.map((id) => getDataById(id)));
}
交替:
function callService(idList) {
return Promise.all(idList.map((id) => getDataById(id)));
}
(旁注:不需要那个箭头函数:
return await Promise.all(idList.map(getDataById));
)
请注意,它们都按以下顺序执行操作:
getDataById
为每个调用id
等待所有这些承诺都实现,或者其中一个失败
如果它们都实现了,则使用结果数组来解析
callService
的承诺(记住,async
函数总是返回承诺)
如果您想getDataById
在对 进行下一次调用之前等待每个调用完成getDataById
,您可以使用一个简单的循环来完成:
// **IF** you wanted to wait for each `getDataById` call to finish
// before starting the next
async function callService(idList) {
const result = [];
for (const id of idList) {
result.push(await getDataById(id));
}
return result;
}
(reduce如果你愿意,你也可以把它硬塞进去,但它不会给你买任何东西。)
但我认为你想要上面的第一个代码块,并行启动所有调用并等待它们完成。
你在评论中说你的老板不希望你使用,Promise.all因为如果任何承诺拒绝,它就会拒绝。确实如此,确实如此。如果你不想那样,你可能想allSettled改用。这是第 4 阶段的提案(例如,在 JavaScript 引擎中积极实施),它很容易被 polyfill。
async function callService(idList) {
return await Promise.allSettled(idList.map(getDataById));
}
交替:
function callService(idList) {
return Promise.allSettled(idList.map(getDataById));
}
结果是一个对象数组,其中已履行的承诺如下所示:
{
status: "fulfilled",
value: (the value)
}
被拒绝的看起来像这样:
{
status: "fulfilled",
reason: (the rejection reason)
}
显然,如果你想转换那个数组,你可以很容易地做到这一点。例如,如果您想返回null无法检索的那些:
async function callService(idList) {
return (await Promise.allSettled(idList.map(getDataById)))
.map(entry => entry.status === "fulfilled" ? entry.value : null);
}
或者,如果您想过滤掉它们:
async function callService(idList) {
return (await Promise.allSettled(idList.map(getDataById)))
.map(entry => entry.status === "fulfilled" ? entry.value : null)
.filter(entry => entry !== null);
}
如果你想同时过滤和映射,我们可以稍微滥用flatMap:-)
async function callService(idList) {
return (await Promise.allSettled(idList.map(getDataById)))
.flatMap(entry => entry.status === "fulfilled" ? entry.value : []);
}
添加回答
举报