【问题标题】:Is it possible to use await in other then for() loop?是否可以在 for() 循环中使用 await ?
【发布时间】:2019-03-15 00:09:38
【问题描述】:

有没有办法在 NOT for 循环(例如 foreach、map)中使用 async/await 调用异步函数,并仅在所有异步函数完成后继续执行其余代码?

const layers = ["layer1", "layer2", "layer3"];

async function connect(layer: string): Promise<object> {
    return new Promise((resolve, reject) => {
        setTimeout(function () {
            resolve(layer);
        }, 1000);
    });
}

(async function () {
    for (let i = 0; i < layers.length; i++) {
        const result = await connect(layers[i]);
        console.log(result, "connected");
    }
    console.log("All layers are connected");
})();

【问题讨论】:

标签: javascript node.js async-await ecmascript-2017


【解决方案1】:

从技术上讲,您“可以”,但您不想这样做。如果您有一系列需要解决的承诺,最好使用Promise.all() 解决它们。

【讨论】:

    【解决方案2】:

    您正在寻找Promise.all()。它获取Promises 的数组(或其他可迭代对象)并返回一个新的Promise,当所有输入Promises 解析时解析。输入 Promises 并行执行(比循环中每个 Promiseawait-ing 好得多)。

    await这个Promise

    const layers = ["layer1", "layer2", "layer3"];
    
    async function connect(layer: string): Promise<object> {
        return new Promise((resolve, reject) => {
            setTimeout(function () {
                resolve(layer);
            }, 1000);
        });
    }
    
    await Promise.all(layers.map(connect));
    console.log('All layers are connected');
    

    【讨论】:

      【解决方案3】:

      可以在async 函数中使用await。因此,将它与async 中使用的除for 之外的其他语句一起使用,即do..whilewhile 循环语句。

      有没有办法在 NOT for 循环中调用异步函数(例如 foreach、map)

      这是另一种情况。像forEach 这样的基于回调的方法有自己的功能。在常规函数中无法使用await

      arr.forEach(() => {
        await ... // syntax error
      });
      

      async 函数与 awaitforEach is a common mistake 一起使用,因为它会导致一个被忽略的承诺:

      arr.forEach(async () => {
        await ... // isn't awaited outside function
      });
      

      可以将async..awaitmap 一起使用是可以接受的,因为它的工作方式是,从async 返回的promise 被map 使用并映射到结果数组:

      const arrOfPromises = arr.map(async () => {
        await ...
      });
      

      为了在map 函数之外等待,Promise 应该被显式链接起来:

      await Promise.all(arrOfPromises);
      

      【讨论】:

      • 看起来 map() 在这种情况下不起作用。 (async function () { const results = layers.map(async (layer) =&gt; { const result = await connect(layer); console.log(result, "connected"); return result; }); console.log("All layers are connected", results); })();这段代码的结果是:All layers are connected [ Promise { &lt;pending&gt; }, Promise { &lt;pending&gt; }, Promise { &lt;pending&gt; } ] layer1 connected layer2 connected layer3 connected
      • 代码中不包含map。但是你应该在某个时候拥有result = await Promise.all(promises)。就像我说的,Promise 应该被显式链接起来,以便在 map 函数之外等待async 是 promise 的语法糖。 Promise 不能通过魔法同步解决。
      • 是的,对不起。知道了。它适用于 Promise.all();那么,使用 Promise.all() 是处理异步函数集合的最佳方式吗?如我的问题所示,使用for 循环有什么缺点?性能?
      • 带有异步函数的集合 - 准确地说是带有 Promise 的集合。 map 调用函数并从它们返回承诺。是的,区别在于性能。 mapawait Promise.all 是并发承诺的秘诀。 forawait 是顺序承诺的秘诀。如果 Promise 不相互依赖并且不会产生问题(一次 100 个并发请求),那么并发是更可取的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-21
      • 1970-01-01
      • 2010-11-26
      • 2017-12-26
      • 1970-01-01
      • 1970-01-01
      • 2015-12-18
      相关资源
      最近更新 更多