【问题标题】:Why does using async-await in map function still return promises and not the resolved values? [duplicate]为什么在 map 函数中使用 async-await 仍然返回 Promise 而不是解析的值? [复制]
【发布时间】:2021-01-10 16:54:16
【问题描述】:

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

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

为什么allImages 仍然是一组承诺而不是一组响应?

【问题讨论】:

  • 每个异步函数都返回一个 Promise。所以结果是一个 Promise 列表。
  • 因为这就是异步函数的作用。 They return a Promise.

标签: javascript asynchronous promise async-await array-map


【解决方案1】:

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

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

Async function 总是立即隐式返回一个 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.
});

如果您有任何其他疑问,请告诉我。

回应 cmets:

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

当您在异步函数中并找到 await 语句时,代码执行“跳转”到 async 范围之外实现了。

JS async/await 只是处理 Promise 的语法糖。而 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.

【讨论】:

  • 谢谢,我已经这样做了,但我不清楚为什么在异步函数内部,执行没有暂停以等待响应? An Async function always immediately and explicitly returns a promise. 如果我在 Array.map 之外使用异步函数,行为会有所不同。
  • @ilyo 请查看我的更新答案。
  • 谢谢,所以如果我理解正确的话,异步函数实际上是在map函数运行完成后才解决的?
  • @ilyo 实际上是的。 This 是更技术性的解释。
猜你喜欢
  • 1970-01-01
  • 2019-04-22
  • 2020-10-02
  • 1970-01-01
  • 2021-05-11
  • 1970-01-01
  • 1970-01-01
  • 2017-09-11
相关资源
最近更新 更多