为什么在 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.