icemanpro
V2EX  ›  Node.js

如何等待 foreach 完成之后才能进行下一步?

  •  
  •   icemanpro · Jun 6, 2020 · 7651 views
    This topic created in 2342 days ago, the information mentioned may be changed or developed.
    foreach 是异步,但在下一步之前,需要得到 foreach 的完成数据。应该如何处理?
    24 replies  •  2020-07-31 10:36:05 +08:00
    bi531334444
    bi531334444
    Jun 6, 2020
    1
    for of + async await ?
    ericls
    ericls
    Jun 6, 2020
    2
    promise.all?
    cxe2v
    cxe2v
    Jun 6, 2020
    3
    foreach 我记得是同步的
    VDimos
    VDimos
    Jun 6, 2020 via Android
    4
    foreach 是异步是啥意思?
    mazai
    mazai
    Jun 6, 2020
    5
    重新定义 foreach👍
    mikicomo
    mikicomo
    Jun 6, 2020
    6
    写 java 的,不过题主的意思我明白了,foreach 中循环的方法体中调用了异步方法,而你又需要在后面的代码中使用 foreach 循环体中生成的数据,对标 java 中的 Future,可以搜一下 js 中怎么实现的
    ljpCN
    ljpCN
    Jun 6, 2020
    7
    别用 foreach,用 map+Promise.all
    px920906
    px920906
    Jun 6, 2020
    8
    php 吗? js 用 promise 的话可以这样:
    ```js
    let queue = Promise.resolve()
    arr.forEach(e => {
    queue = queue.then(() => someAsyncFunc(e))
    })
    ```

    当然 async/await 也可以
    ```js
    async (function() {
    arr.forEach(e => {
    await someAsyncFunc(e)
    })
    })()
    ```
    cnrting
    cnrting
    Jun 6, 2020 via iPhone
    9
    for 循环不是同步的吗???
    Trim21
    Trim21
    Jun 6, 2020 via Android
    10
    楼主的意思是 foreach 传进的那个函数是异步的…
    seki
    seki
    Jun 6, 2020
    11
    用 bluebird.each 或者 p-each-series 这样的库
    meteor957
    meteor957
    Jun 6, 2020 via Android
    12
    reduce
    will0404
    will0404
    Jun 6, 2020
    13
    ```
    const arr = [1, 2, 3];
    const promises = [];
    arr.forEach(v => {
    promises.push(Promise.resolve(v));
    });
    Promise.all(promises).then(result => {
    console.log(result); // [1,2,3]
    });
    ```
    GG668v26Fd55CP5W
    GG668v26Fd55CP5W
    Jun 6, 2020 via iPhone
    14
    foreach 是同步的好吗?
    S23VqeW93WZLlm6s
    S23VqeW93WZLlm6s
    Jun 6, 2020
    15
    1. 继发: Loop await 即可
    2. 继发 Iterator: for await of 即可
    3. 并发: Promise.all([].map(async item => await todo(item))) 是比较简单的方式
    4. 并发但忽略 reject 直到所有异步都完成: 3 改成 Promise.allSettled 。其他的并发但状态需求不同可参考其他 Promise 静态方法

    8 楼的例子还有其他几楼由明显错误,await 只能在 async 下,即便 forEach 了 async,在可读性上也是误以为继发的并发任务,有阅读歧义。此外 forEach 是典型的副作用的函数。
    a132811
    a132811
    Jun 6, 2020
    16
    多提了下。
    @WittBulter 最新的 v8 已经支持 top await 了,不用限制 await 在 async 了。

    目前 deno 、chrome 80 、firefox 72 已支持 top await.
    ````
    export default config = await Promise.resolve({env:'dev'})
    ```
    gauzung
    gauzung
    Jun 6, 2020
    17
    async fun(){for(...){await ...}}
    每次循环请求一个接口,成功 /失败后才执行下一次循环
    JayLin1011
    JayLin1011
    Jun 6, 2020
    18
    for..await...of 或者 Promsie.all(),异步并发问题一般需要计数器作为哨兵变量。
    wangyzj
    wangyzj
    Jun 7, 2020
    19
    foreach 是同步的
    qinfensky
    qinfensky
    Jun 7, 2020 via iPhone
    20
    @px920906 你这个是不是有问题的呢?在 foreach 的匿名函数中 await 应该是不可以的吧。作用域变动了,用 for 就可以 await
    px920906
    px920906
    Jun 7, 2020
    21
    @WittBulter @qinfensky 是的,,写了个不负责任的回答,惭愧,谢谢指出。
    自己试了一下,即使 async 放在 forEach 的匿名函数前也没用,会并行执行,查了一下这好像是个常见的误区。
    http://objcer.com/2017/10/12/async-await-with-forEach/
    https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop
    ruby109
    ruby109
    Jun 9, 2020
    22
    const a = await Promise.all(array.map(async element => {
    return await asyncFunction();
    });
    source
    source
    Jul 10, 2020
    23
    指出一点:forEach 的回调不能直接套 async/await
    其他的方式都没问题,比如 promise.all
    jake361
    jake361
    Jul 31, 2020
    24
    foreach 就是同步得啊,你的意思是不是在 foreach 里面异步调用?
    有两种解决方案,一个是 Promise all,配合 async await,最新版本的 node 应该支持了
    如果是老版本的 node,有一个库 http://caolan.github.io/async/v3/, 应该可以解决你的问题
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1296 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 67ms · UTC 20:35 · PVG 04:35 · LAX 12:35 · JFK 15:35
    ♥ Do have faith in what you're doing.