s_curry_s
s_curry_s

Reputation: 3432

While loop in Javascript with a Callback

I am trying to write the Pseudocode given here https://dev.twitter.com/docs/misc/cursoring with javascript using node-oauth https://github.com/ciaranj/node-oauth. However I am afraid because of the nature of the callback functions the cursor is never assigned to the next_cursor and the loop just runs forever. Can anyone think a workaround for this?

module.exports.getFriends = function (user ,oa ,cb){
  var friendsObject = {};
  var cursor = -1 ;
  while(cursor != 0){
    console.log(cursor);
      oa.get(
        'https://api.twitter.com/1.1/friends/list.json?cursor=' + cursor + '&skip_status=true&include_user_entities=false'
        ,user.token //test user token
        ,user.tokenSecret, //test user secret
        function (e, data, res){
          if (e) console.error(e);
          cursor = JSON.parse(data).next_cursor;
          JSON.parse(data).users.forEach(function(user){
            var name = user.name;
            friendsObject[name + ""] = {twitterHandle : "@" + user.name, profilePic: user.profile_image_url};
          });        
          console.log(friendsObject);   
        }
      );
    }  
  }

Upvotes: 4

Views: 10669

Answers (2)

diversario
diversario

Reputation: 1014

I strongly suggest using async for this. It's made for situations like yours and handles concurrency and execution for you. You will simply end up writing something that does the same thing as async, only yours will not be as tested.

Upvotes: 1

Alberto Zaccagni
Alberto Zaccagni

Reputation: 31560

Suppose your code is wrapped in a function, I'll call it getFriends, basically it wraps everything inside the loop.

function getFriends(cursor, callback) {
  var url = 'https://api.twitter.com/1.1/friends/list.json?cursor=' + cursor + '&skip_status=true&include_user_entities=false'
  oa.get(url, user.token, user.tokenSecret, function (e, data, res) {
    if (e) console.error(e);
    cursor = JSON.parse(data).next_cursor;
    JSON.parse(data).users.forEach(function(user){
      var name = user.name;
      friendsObject[name + ""] = {twitterHandle : "@" + user.name, profilePic: user.profile_image_url};
    });        
    console.log(friendsObject);
    callback(cursor); 
  });
}

In nodejs all io is done asynchronously, so you will loop a lot more than needed, before actually changing cursor, what you need is loop only when you receive a response from the Twitter API, you could do something like this:

function loop(cursor) {
  getFriends(cursor, function(cursor) {
    if (cursor != 0) loop(cursor);
    else return;
  });
}

You start it by calling loop(-1), of course this is just one way of doing it.

If you prefer you could use an external library, like async.

Upvotes: 6

Related Questions