node.js - 按顺序运行大量的 Promise

标签 node.js promise

一个nodejs项目。我尝试使用promise连续运行大量(大约100k)任务。我能做的就是用 Q 将其转换为 workOnebyOne 函数。有更好的方法吗?

function workOnebyOne(items, worker) {
  var deferred = Q.defer()

  function _doNext() {
    if (items.length === 0) {
      deferred.resolve()
      return
    }
    var item = items[0]
    synchronize(worker, item)
      .then(function (result) {
        items = items.slice(1)
        deferred.notify({
          item: item,
          result: result
        })
        _doNext()
      }, function () {
        items = items.slice(1)
        _doNext()
      })
  }

  _doNext()

  return deferred.promise
}

utils.workOnebyOne(tasks, workerFunction)

最佳答案

您基本上是在此处重新实现排队。在 Bluebird Promise 中(速度更快,消耗的内存更少,有助于完成 100K 任务),您可以使用 Promise.each

在 Q 中,您通常可以在任务数组上使用 .reduce 来立即对它们进行排队 - 但是,如果有 100K 个元素,那么在 Q Promise 中创建 100K Promise 队列会使 Node 崩溃(同样,这是 Q, bluebird 或当 promise 时)会处理得很好)。这个(此处不正确)解决方案看起来像:

var res = tasks.reduce(function(p, c){
    return p.then(function(){ return workerFunction(c); });
}, Q());

对于短队列(Q 中 < 500 个 promise ),这效果很好。

因此,由于旧的库选择以及涉及大量的 promise ,您实际上无法优雅地解决它,使用回调队列之类的方法非常接近您唯一的方法。我也会避免 notify 因为它正在被删除(甚至从 Q 中删除),并且通常是一个糟糕的 API(组合得不好)。

关于node.js - 按顺序运行大量的 Promise,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27319889/

相关文章:

node.js - 使用除 ObjectId 以外的 SchemaTypes 来填充 (Mongoose)

javascript - 使用 WinJS 进行错误处理

angularjs 在 $http 成功中中断 forEach

node.js - Sequelize errno : 150 "Foreign key constraint is incorrectly formed"

node.js - 在 node.js 中循环 promise

javascript - 如何找出 jQuery 事件的结束

javascript - 尝试从 JavaScript 客户端的 PHP 服务器捕获托管的 PayPalCheckoutSdk.Orders.OrdersCreateRequest 错误

node.js - 调用gundb.once回调并显示错误消息: Error: No ACK received yet

javascript - 有没有办法在 nightjs 中处理弹出窗口

node.js - GraphQL 架构定义中出现“获取对象”异常