当前位置: 首页 > 面试题库 >

所有异步forEach回调完成后的回调

穆智刚
2023-03-14
问题内容

如标题所示。我该怎么做呢?

我想whenAllDone()在forEach循环遍历每个元素并完成一些异步处理后调用。

[1, 2, 3].forEach(
  function(item, index, array, done) {
     asyncFunction(item, function itemDone() {
       console.log(item + " done");
       done();
     });
  }, function allDone() {
     console.log("All done");
     whenAllDone();
  }
);

有可能使它像这样工作吗?当forEach的第二个参数是一个回调函数,该函数一旦经过所有迭代便会运行?

预期产量:

3 done
1 done
2 done
All done!

问题答案:

Array.forEach 不能提供这种效果(如果可以的话),但是有几种方法可以实现您想要的效果:

使用一个简单的计数器

function callback () { console.log('all done'); }

var itemsProcessed = 0;

[1, 2, 3].forEach((item, index, array) => {
  asyncFunction(item, () => {
    itemsProcessed++;
    if(itemsProcessed === array.length) {
      callback();
    }
  });
});

(由于@vanuan等),这种方法可确保在调用“完成”回调之前处理所有项目。您需要使用在回调中更新的计数器。依赖于index参数的值不能提供相同的保证,因为不能保证异步操作的返回顺序。

使用ES6承诺

(承诺库可用于较旧的浏览器):

  1. 处理所有保证同步执行的请求(例如1到2然后3)

    function asyncFunction (item, cb) {
    

    setTimeout(() => {
    console.log(‘done with’, item);
    cb();
    }, 100);
    }


    let requests = [1, 2, 3].reduce((promiseChain, item) => {
    return promiseChain.then(() => new Promise((resolve) => {
    asyncFunction(item, resolve);
    }));
    }, Promise.resolve());

    requests.then(() => console.log(‘done’))

  2. 处理所有异步请求而无需“同步”执行(2个完成可能比1个完成快)

    let requests = [1,2,3].map((item) => {
    return new Promise((resolve) => {
      asyncFunction(item, resolve);
    });
    

    })

    Promise.all(requests).then(() => console.log(‘done’));

使用异步库

还有其他异步库(异步是最流行的),它们提供了表达所需内容的机制。

编辑

对问题的正文进行了编辑,以删除以前同步的示例代码,因此我更新了答案以进行澄清。原始示例使用类似同步的代码来建模异步行为,因此适用以下内容:

array.forEach是同步的,也是如此res.write,因此您只需在调用foreach之后放置回调即可:

  posts.foreach(function(v, i) {
    res.write(v + ". index " + i);
  });

  res.end();


 类似资料:
  • 问题内容: 如何在异步forEach循环后添加回调函数? 这里是一些更好的上下文: 控制器: 服务: 问题答案: 正如安德鲁所说,使用和延迟对象应该可以使您实现目标。 您想使用 这将确保您的所有promise对象都已解析,然后您可以回叫 jsfiddle上的示例 可以,但不能通话 使用延迟对象,您可以访问Promise,在此可以一起更改连续的调用。解析延迟的对象时,它将执行foreach,然后执行

  • 我想在完成后执行回调,但它不能正常工作。我该怎么做呢?

  • 问题内容: 如何快速进行异步回调?我正在为我的应用程序编写一个小框架,因为它应该同时在iOS和OS X上运行。因此,我将非特定于设备的主要代码放入该框架中,该框架还处理对我的在线api的请求。很显然,我也希望应用程序的GUI以及ViewController在api请求完成后立即做出反应。在Objective- C中,我通过将包含必须在id变量中调用的函数以及函数本身的视图保存在选择器变量中的视图来

  • 几周前刚开始学Node.js....我不明白为什么“products”数组包含null而不是所需的对象.... 在第13行,当我对对象进行控制台日志记录时,我得到了所需的对象,但我不明白当我在map函数完成它的执行后在第40行对它们进行控制台日志记录时,它们为什么是空的.... 如果数组长度是2(这意味着推入成功),为什么里面存储的对象仍然是空的,而不是我想要存储的对象? 控制台输出 订单模式

  • 视频处理完成后的回调 当处理完毕视频后(上传、转码、审核都完成后),Spark 平台会通过由上传接口入参 notify_url 指定的 HTTP/HTTPS 地址以 GET 方式发起回调。若用户网站地址使用HTTPS协议进行数据安全传输时,用户需保证其拥有的CA证书是合法的。 用户指定的 notify_url 符合以下四种 notify_url 格式之一即为合法: 1、http://domain

  • 稳定性: 1 - 试验的 async_hooks 模块提供了一个用于注册回调函数的 API,这些回调函数可追踪在 Node.js 应用中创建的异步资源的生命周期。可以通过以下方式使用: const async_hooks = require('async_hooks'); Terminology An asynchronous resource represents an object with