【问题标题】:Adding to an array asynchronously in Node.js在 Node.js 中异步添加到数组
【发布时间】:2011-11-30 23:18:36
【问题描述】:

我对这种类型的编程很陌生,并且在从嵌套调用中填充数组时遇到了一些麻烦。我很确定这需要使用回调来完成,但我无法将我的大脑包裹在它周围。闭包也必须在这里发挥作用。我尝试在网上搜索类似的示例,但没有找到太多。

这是我的原始代码。我尝试了几种不同的方法,但没有成功。

TaskSchema.statics.formatAssignee = function(assignees) {
  var users = [];

  assignees.forEach(function(uid) {
    mongoose.model('User').findById(uid, function(err, user) {
      users.push({
          name: user.name.full
        , id: user.id
      });
    });
  });

  return users;
}

【问题讨论】:

    标签: arrays node.js asynchronous callback


    【解决方案1】:

    查看async,它有一个异步 foreach 循环。

    编辑

    这是来自async library的foreach方法

    async.forEach = function (arr, iterator, callback) {
        if (!arr.length) {
            return callback();
        }
        var completed = 0;
        _forEach(arr, function (x) {
            iterator(x, function (err) {
                if (err) {
                    callback(err);
                    callback = function () {};
                }
                else {
                    completed += 1;
                    if (completed === arr.length) {
                        callback();
                    }
                }
            });
        });
    };
    var _forEach = function (arr, iterator) {
        if (arr.forEach) {
            return arr.forEach(iterator);
        }
        for (var i = 0; i < arr.length; i += 1) {
            iterator(arr[i], i, arr);
        }
    };
    

    【讨论】:

    • 如果您查看源代码,您会看到基本相同的模式:执行操作,递增计数器,如果 counter==input.length 然后调用我提到的回调。基本上是DIY或图书馆的选择,但思路是一样的。
    • @z5h 对,变成递归循环了。
    • 嘿机会,我检查了异步,它看起来非常有用。谢谢推荐。
    【解决方案2】:

    我真的很喜欢下面的模式(递归是异步循环最优雅的解决方案):

    TaskSchema.statics.formatAssignee = function(assignees, callback) {
      var acc = []
        , uids = assignees.slice()
      (function next(){
        if (!uids.length) return callback(null, acc);
    
        var uid = uids.pop()
        mongoose.model('User').findById(uid, function(err, user) {
          if (err) return callback(err);
          acc.push({
            name: user.name.full
          , id: user.id
          });
          next();
        });
      })();
    }
    

    【讨论】:

    • 谢谢阿德里安,这成功了。我最终将它与下面提到的异步库一起使用来处理数组。我想我可以用调用 async.map 来替换这个递归函数,但至少我现在知道如何在不依赖库的情况下解决这个问题。
    【解决方案3】:

    你可以这样做:
    给 formatAssignee 一个回调。
    倒数您需要向用户推送多少用户。
    推送最后一个后,使用参数users 调用回调。

    【讨论】:

      猜你喜欢
      • 2015-08-18
      • 2018-03-02
      • 1970-01-01
      • 2016-07-10
      • 2015-10-02
      • 2013-05-29
      • 2018-03-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多