【问题标题】:Callback after multiple asynchronous calls?多次异步调用后回调?
【发布时间】:2015-12-31 09:41:28
【问题描述】:

我正在使用 Gmail API 循环检索邮件并为每封邮件执行 req.write()。每个 api 调用都有一个回调,但是我如何知道整个集合何时完成以便我可以结束响应?我尝试了以下方法,但注意到回调不是按照数组索引的顺序执行的,所以我不能只做我注释掉的那一行。

for (var i = 0; i < messages.length; i++) {
            var message = messages[i];
            console.log('- %s', message.id);
            (function(e){
              var request = gmail.users.messages.get({
                  auth:auth,
                  id:message.id,
                  userId: 'me'
                }, function(err, response) {
                  if(err) {
                    console.log('API returned an error: ' +err);
                    return;
                  }
                  res.write(JSON.stringify(response,null,'\t'));
                  console.log(e);
                  //if(e==messages.length-1) res.end();
                }
              );
            })(i);
}

【问题讨论】:

标签: javascript node.js asynchronous scope


【解决方案1】:

不过,您走在正确的轨道上。由于在循环完成之前您不会收到 任何 回调,因此您只需跟踪您收到了多少回调以及何时达到 messages.length,您就知道您已经完成了:

var completed = 0;
for (var i = 0; i < messages.length; i++) {
    var message = messages[i];
    console.log('- %s', message.id);
    var request = gmail.users.messages.get({
        auth: auth,
        id: message.id,
        userId: 'me'
    }, function(err, response) {
        if (err) {
            // Should increment and check `completed` here too,
            // not sure what you want to do though
            console.log('API returned an error: ' + err);
            return;
        }
        res.write(JSON.stringify(response, null, '\t'));
        if (++completed == messages.length) {
            res.end();
        }
    });
}

假设在此期间 messages 不会发生任何变化(影响其长度)。如果这个假设不成立,你可以反转completed,称之为pending,当它到达0时你就完成了:

var pending = 0;
for (var i = 0; i < messages.length; i++) {
    var message = messages[i];
    console.log('- %s', message.id);
    var request = gmail.users.messages.get({
        auth: auth,
        id: message.id,
        userId: 'me'
    }, function(err, response) {
        if (err) {
            // Should decrement and check `pending` here too,
            // not sure what you want to do though
            console.log('API returned an error: ' + err);
            return;
        }
        res.write(JSON.stringify(response, null, '\t'));
        if (--pending === 0) {
            res.end();
        }
    });
    ++pending;
}

【讨论】:

    猜你喜欢
    • 2013-04-27
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    • 1970-01-01
    • 1970-01-01
    • 2019-05-15
    • 2017-07-18
    • 2018-12-11
    相关资源
    最近更新 更多