1

I'm using the Gmail API to retrieve messages in a loop and do a req.write() for each message. There's a callback for each api invocation, but how do I know when the whole set is done so I can end the response? I tried the following but noticed that the callbacks are not executed in order of array index so I can't just do the line I commented out.

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);
}
1
  • Solutions here and here. Commented Oct 3, 2015 at 6:47

1 Answer 1

2

You're on the right track, though. Since you won't get any callbacks until your loop is completed, you can just keep track of how many callbacks you've gotten and when it reaches messages.length, you know you're done:

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();
        }
    });
}

That assumes nothing will change messages in the meantime (affecting its length). If that assumption isn't valid, you can just invert completed, call it pending, and you're done when it reaches 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;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.