为什么在map函数中使用async wait仍然返回promise而不是解析的值



我有一个对链接数组的API调用,我想使用映射函数来保存所有响应

const allImages = list.map(async (imageLink) => {
const image = await axios.get(imageLink);
return image.data.primaryImage;
});

为什么allImages仍然是一系列承诺而不是一系列回应?

因为Array.map方法本身不是async方法。事实上,我必须记住JavaScript是一种单线程语言。真正可以同时发生的操作只有由您的平台处理的I/O操作。

话虽如此,在您的情况下,Array.map将遍历整个数组,并返回一个新数组,其中包含每个原始项的回调返回值。

异步函数总是立即隐式返回promise,然后将其解析为函数的显式返回值。

这就是为什么你会得到一系列承诺。

如果你想使用响应,你可以做的是这样的:

const allImages = list.map(async (imageLink) => {
const image = await axios.get(imageLink);
return image.data.primaryImage;
});
Promise.all(allImages).then((responses) => {
console.log(responses); // THIS ARE THE RESPONSES YOU ARE LOOKING FOR.
});

如果你还有其他疑问,请告诉我。

回复评论:

JS代码的执行永远不能暂停,它会冻结你的引擎,并破坏JS异步实现的整个目的。

当您在异步函数内部并找到一个await语句时,代码执行"跳转"到async作用域"Promise"之外,以在与await语句相关的Promise完成后立即恢复执行。

JS async/await只是处理promise的语法糖。承诺只是处理回调的语法糖。

使用代码查看以下示例:

let count = 0;
const allImages = list.map(async (imageLink) => {
const image = await axios.get(imageLink);
// CODE EXECUTION 'STOPS' HERE, BUT CONTINUES OUTSIDE OF THE ASYNC SCOPE. Array.map PASSES TO NEXT ITEM.
count++;
console.log('A' + count);
return image.data.primaryImage; // THIS RESOLVES THE PROMISE.
});
// CODE EXECUTION CONTINUES
console.log('B');
Promise.all(allImages).then(() => {
// ALL PROMISES HAVE BEEN FULFILLED.
console.log('C');
});
/*
EXPECTED OUTPUT ORDER:
B
A1, A2, A3... (depending on http responses arrival order)
C
*/

希望有一个更直观的例子可以像你所期望的那样工作:

(async () => {
for (let i = 0; i < list.length; i++) {
const imageLink = list[i];
const image = await axios.get(imageLink);
// CODE EXECUTION 'STOPS' HERE.
list[i] image.data.primaryImage;
}
console.log(list); // AN ARRAY OF RESPONSES.
})();
// HOWEVER, CODE EXECUTION NEVER REALLY STOPS AND CONTINUES HERE. OUTSIDE OF THE async SCOPE.

最新更新