1

I have this function:

function tryStartLocalTrendsFetch(woeid) {
    var userIds = Object.keys(twitClientsMap);
    var isStarted = false;

    for (var i = 0; i < userIds.length; i++) {
        var userId = userIds[i];
        var twitClientData = twitClientsMap[userId];
        var isWoeidMatch = (woeid === twitClientData.woeid);
        if (isWoeidMatch) {

            startLocalTrendsFetch(woeid, twitClientData, function (err, data) {
                if (err) {
                    // Couldn't start local trends fetch for userId: and woeid:
                    isStarted = false;
                } else {
                    isStarted = true;
                }
            });
            // This will not obviously work because startLocalTrendsFetch method is async and will execute immediately
            if (isStarted) {
                break;
            }
        }
    }
    console.log("No users are fetching woeid: " + woeid);
}

The gist of this method is that I want the line if (isStarted) { break; } to work. The reason is that if it's started it should not continue the loop and try to start another one.

I'm doing this in NodeJS.

Peter Warbo
  • 11,136
  • 14
  • 98
  • 193
  • 2
    Try looking up the `async` Node package on NPM. – Scimonster Jun 24 '15 at 13:51
  • I'd make i an index variable inside the loop, and change that outer 'for' loop into a while(!isStarted && i – David W Jun 24 '15 at 13:54
  • If you're up to refactor your code to avoid callbacks, what @Scimonster said, `async`, will work. I'd recommend Promises, [bluebird](https://github.com/petkaantonov/bluebird) is great. My strongest recommendation would be FRP with [Kefir](https://rpominov.github.io/kefir/). – Ahmed Fasih Jun 24 '15 at 13:56

2 Answers2

2

try to use a recursive definition instead

function tryStartLocalTrendsFetch(woeid) {
  var userIds = Object.keys(twitClientsMap);
  recursiveDefinition (userIds, woeid);
}

function recursiveDefinition (userIds, woeid, userIndex)
  var userId = userIds[userIndex = userIndex || 0];
  var twitClientData = twitClientsMap[userId];
  var isWoeidMatch = (woeid === twitClientData.woeid);
  if (isWoeidMatch && userIndex<userIds.length) {
      startLocalTrendsFetch(woeid, twitClientData, function (err, data) {
          if (err) {
            recursiveDefinition(userIds, woeid, userIndex + 1)
          } else {
            console.log("No users are fetching woeid: " + woeid);
          }
      });
  } else {
    console.log("No users are fetching woeid: " + woeid);
  }
}
Khalid
  • 4,730
  • 5
  • 27
  • 50
1

You may also use async (npm install async):

var async = require('async');

async.forEach(row, function(col, callback){
    // Do your magic here
    callback();  // indicates the end of loop - exit out of loop
    }, function(err){
        if(err) throw err;
    });

More material to help you out: Node.js - Using the async lib - async.foreach with object

Community
  • 1
  • 1
Hamed
  • 869
  • 10
  • 26