我试图弄清楚为什么承诺在for...of
和map()
内部似乎有所不同。
data
是{app: MY_APP, link: MY_LINK}
形式的对象数组。我正在尝试将其转换为{app: MY_APP, status: true OR false}}
的形式。函数checkLink()
是异步的,因为它使用node-fetch
并基本上返回给定的链接是否为200。使用for...of
,我得到了所需的对象:
let objToSend = [];
for (obj of data) {
objToSend.push({ app: obj.app, status: await checkLink(obj.link) });
}
// returns [{app: MY_APP, status: true}, ...]
但是使用map
,如下所示,我得到了一系列待处理的Promise。任何帮助将不胜感激:
let objToSend = data.map(async obj => {
return {
app: obj.app,
status: await checkLink(obj.link)
};
});
// returns [ Promise { <pending> }, ...]
我还尝试在Promise.all(objToSend)
代码之后执行map
,但是它返回了Promise { <pending> }
答案 0 :(得分:1)
await
总是停止执行其中的async function
,在两种情况下它的工作方式都没有不同。但是,在后面的示例中,您确实调用了一些async function
,而这些调用将评估为Promise,而在您的第一个示例中,所有这些await
都在同一async function
中。 / p>
我还尝试在地图代码之后执行
Promise.all(objToSend)
,但它返回Promise { <pending> }
是的,await
,您会得到一系列结果。
答案 1 :(得分:1)
Async functions始终为returns Promises。在您的map函数中,当回调函数返回promise时,将创建一个promise数组。
要将其转换为您的格式,请与Promise.all()
一起使用:
(async()=>{
let objToSend = await Promise.all(data.map(async obj => {
return {
app: obj.app,
status: await checkLink(obj.link)
};
}));
console.log(objToSend) //[{app: MY_APP, status: true}, ...]
})()
答案 2 :(得分:1)
我将把解释留给其他答案,但只想指出在性能上也有差异。
您的第一个解决方案会在每次迭代中等待承诺的解决。仅在上一个已解决的情况下才呼叫checkLink
。这是一个顺序解决方案。
check link1 => wait => check link2 => wait => check link3 => wait
第二种解决方案遍历每个元素并发出请求,而无需等待promise解决(因此,将返回一个promise数组)。如果您等待所有承诺都得到解决,您会发现此解决方案要快得多,因为请求是并行发送的。
check link1 => check link2 => check link3 => wait for all
const sleep = async ms => new Promise(resolve => setTimeout(resolve, ms));
async function checkLink(link) {
await sleep(Math.random() * 1000 + 500); // sleep between 500 and 1500 ms
console.log(link);
return `status #${link}`;
}
(async function () {
const data = new Array(5).fill().map((_, index) => ({ app: "app", link: index }));
let objToSend;
console.log("solution #1");
objToSend = [];
for (let obj of data) {
objToSend.push({ app: obj.app, status: await checkLink(obj.link) });
}
console.log(objToSend);
console.log("==============================================");
console.log("solution #2");
objToSend = await Promise.all(data.map(async obj => {
return {
app: obj.app,
status: await checkLink(obj.link)
};
}));
console.log(objToSend);
})();
在摘要中,第一个解决方案在2500到7500毫秒之间花费了500/1500 * 5 = 2500/7500
。而第二种解决方案则需要500到1500毫秒(取决于要解决的最慢值)。