【问题标题】:Node.js how to _.each internal callbacks synchronouslyNode.js 如何同步 _.each 内部回调
【发布时间】:2013-06-05 15:27:13
【问题描述】:

我是 node.js 的新手,我不知道如何控制程序流程,以便我的函数等待带有内部回调的 Underscore _.each() 块。我真的很想避免令人发指的回调炖菜。这个块在一个已经被 nimble 的 .series([]) 控制的链中

function (callback) { //get common friends    
    _.each(User.friends, function (friend) { //I NEED THE FLOW TO WAIT TIL THIS COLLECTION HAS ITERATED AND ALL THE CALLBACKS ARE COMPLETE
        request.get({
            url: 'https://graph.facebook.com/me/mutualfriends/' + friend.id + '?access_token=' + User.accessToken,
            json: true
        }, function (error, response, body) { //NEED TO WAIT TIL THESE ARE ALL COMPLETED
            if (!error && response.statusCode == 200) {
                console.log("common friends", body.data);

            } else {
                console.log(error);
            }
        });

    }, this);

    callback(); //Nimble's serialization callback fires immediately
},

我尝试了以下使用 async.each 的建议,但我无法触发迭代完成回调,以告诉 nimble 的 .series 函数继续到下一个块。

async.each(User.friends, function(friend) {
        request.get({
        url: 'https://graph.facebook.com/me/mutualfriends/'+friend.id+'?access_token=' + User.accessToken,
        json: true
        }, function (error, response, body) { //NEED TO WAIT TIL THESE ARE ALL COMPLETED
            if (!error && response.statusCode == 200) {
                console.log("common friends",body.data);

            } else {
                console.log(error);
            }
        });


    },function(err) {console.log('Final callback');callback();}); //THIS CALLBACK DOESN'T FIRE - NIMBLE JUST SITS AND WAITS

【问题讨论】:

  • 考虑使用 Promise。
  • 这有点简洁。 :)

标签: node.js asynchronous underscore.js each


【解决方案1】:

您的代码几乎是正确的。必须要传递并使用回调函数,否则 Async 不知道何时调用最终回调。

async.each(User.friends, function(friend, cb) {
    request.get({
        url: 'https://graph.facebook.com/me/mutualfriends/' + friend.id + '?access_token=' + User.accessToken,
        json: true
    }, function(error, response, body) { //NEED TO WAIT TIL THESE ARE ALL COMPLETED
        if (!error && response.statusCode == 200) {
            console.log("common friends", body.data);
            cb(null);
        } else {
            console.log(error);
            callback(error);
        }
    });
}, function(err) {
    console.log('Final callback', err);
    callback();
});

【讨论】:

  • 谢谢 - 我想我现在明白了。我对迭代器函数的回调和 .each() 函数感到困惑。 arr - An array to iterate over. iterator(item, **callback**) - A function to apply to each item in the array. The iterator is passed a callback(err) which must be called once it has completed. If no error has occured, the callback should be run without arguments or with an explicit null argument. callback(err) - A callback which is called after all the iterator functions have finished, or an error has occurred.
【解决方案2】:

试试这个。

function (callback) { //get common friends  
 var completeCount = 0;  
  _.each(User.friends, function (friend) { 
    request.get({
        url: 'https://graph.facebook.com/me/mutualfriends/' + friend.id + '?access_token=' + User.accessToken,
        json: true
    }, function (error, response, body) { //NEED TO WAIT TIL THESE ARE ALL COMPLETED
        if (!error && response.statusCode == 200) {
            console.log("common friends", body.data);

        } else {
            console.log(error);
        }

        completeCount++;

        // complete count check           
        if( completeCount === User.friends.length ){
           callback()
        }
    });

  }, this);    
},

【讨论】:

  • 感谢您提供这种替代方法。
【解决方案3】:

您可以为此使用async 模块。

async.each

您的代码应如下所示:

async.each(User.friends, function(friend, cb) {
  var req = {
    url: 'https://graph.facebook.com/me/mutualfriends/'+friend.id+
      '?access_token='+User.accessToken,
    json: true
  };
  request.get(req, function(err,response,body) {
    if(err) { console.log(err); cb(true); return; }
    console.log("common friends",body.data);
    // each function call has to finish by calling `cb`
    cb(false);
  });
},
function(err) {
  if(err) return;
  console.log('Final callback');
  callback(); // here is your final callback
}
);

【讨论】:

  • 我正在尝试,但我无法触发迭代完成回调。我已经用新代码编辑了问题。
  • 您的迭代函数不包含回调,也不执行任何类型的回调。仔细阅读文档。
  • 我一定是误解了一些基本的东西:function(err) {console.log('Final callback');...;});是回调,根据文档“callback(err) - 在所有迭代器函数完成或发生错误后调用的回调。”
  • @SimonHill 在您问题的async 代码中,您没有将第二个参数传递给迭代器,这是一个回调函数。如果您不调用它,则假定您的异步工作尚未完成。
  • 异步使用cb(null),而不是cb(false)
猜你喜欢
  • 1970-01-01
  • 2013-11-20
  • 2012-05-14
  • 2012-06-03
  • 1970-01-01
  • 1970-01-01
  • 2017-03-19
  • 1970-01-01
  • 2013-10-16
相关资源
最近更新 更多