为什么在 map 函数中使用 async-await 仍然 return 承诺而不是解析值?
Why does using async-await in map function still return promises and not the resolved values?
我有一个 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
将遍历整个数组,并将 return 一个新数组,其中包含每个原始回调中的 returned 值项目。
一个 Async function 总是立即和隐含地 return 一个承诺,然后将解析为您的函数的显式 returned 值。
这就是为什么你会得到一系列承诺。
如果你想使用回复,你可以做的是这样的:
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
语句时,代码执行 'jumps' 在 async
范围之外 'promising' 以尽快恢复它离开的地方因为与 await
语句相关的 Promise 已实现。
JS async/await 只是处理 promise 的语法糖。而 promises 只是处理回调的语法糖。
使用您的代码查看以下示例:
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.
我有一个 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
将遍历整个数组,并将 return 一个新数组,其中包含每个原始回调中的 returned 值项目。
一个 Async function 总是立即和隐含地 return 一个承诺,然后将解析为您的函数的显式 returned 值。
这就是为什么你会得到一系列承诺。
如果你想使用回复,你可以做的是这样的:
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
语句时,代码执行 'jumps' 在 async
范围之外 'promising' 以尽快恢复它离开的地方因为与 await
语句相关的 Promise 已实现。
JS async/await 只是处理 promise 的语法糖。而 promises 只是处理回调的语法糖。
使用您的代码查看以下示例:
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.