11
  async.map(list, function(object, callback) {
    async.series([
      function(callback) {
        console.log("1");

        var booltest = false;
        // assuming some logic is performed that may or may not change booltest
        if(booltest) {
            // finish this current function, move on to next function in series
        } else {
           // stop here and just die, dont move on to the next function in the series
        }

        callback(null, 'one');
      },
      function(callback) {
        console.log("2");
        callback(null, 'two');
      }
    ],
    function(err, done){
    });
  });

Is there some way such that if function1 if booltest evaluates to true, don't move on to the next function that outputs "2"?

Bergi
  • 513,640
  • 108
  • 821
  • 1,164
Rolando
  • 44,077
  • 84
  • 230
  • 353
  • 1
    `return callback('stop')` will stop the execution of your series and call async callback function with `err = 'stop'`. – Leonid Beschastny May 07 '13 at 16:00
  • Could you show an example of this? I dont seem to know where that variable(flag) would go assuming booltest has to reset itself somewhere at the start of processing the element in the list. – Rolando May 07 '13 at 16:00

4 Answers4

22

The flow will stop if you callback with true as your error argument, so basically

if (booltest)
     callback(null, 'one');
else
     callback(true);

Should work

drinchev
  • 17,524
  • 3
  • 57
  • 86
  • When you say callback with false, but the callback(true)... how is that false? – Rolando May 07 '13 at 17:27
  • Well your first argument 'null' is actually your err argument. Just set it to true, to stop execution of your process. It's my mistake. Sorry – drinchev May 07 '13 at 17:37
  • 2
    I don't think that's proper design. The first argument is meant to be an error. Async happens to stop processing if the callback is called, but using it as a general way to stop processing for arbitrary reason seems weird to me. – Myrne Stol May 07 '13 at 17:50
  • 5
    From the documentation : *If any functions in the series pass an error to its callback, no more functions are run and the callback for the series is immediately called with the value of the error.* https://github.com/caolan/async#series – drinchev May 07 '13 at 18:11
2

I think the function you are looking for is async.detect not map.

from https://github.com/caolan/async#detect

detect(arr, iterator, callback)

Returns the first value in arr that passes an async truth test. The iterator is applied in parallel, meaning the first iterator to return true will fire the detect callback with that result. That means the result might not be the first item in the original arr (in terms of order) that passes the test.

example code

async.detect(['file1','file2','file3'], fs.exists, function(result){
    // result now equals the first file in the list that exists
});

You could use that with your booltest to get the result you want.

mikkom
  • 3,158
  • 4
  • 23
  • 35
1

To make it logical, you could just rename error to something like errorOrStop:

var test = [1,2,3];

test.forEach( function(value) {
    async.series([
        function(callback){ something1(i, callback) },
        function(callback){ something2(i, callback) }
    ],
    function(errorOrStop) {
        if (errorOrStop) {
            if (errorOrStop instanceof Error) throw errorOrStop;
            else return;  // stops async for this index of `test`
        }
        console.log("done!");
    });
});

function something1(i, callback) {
    var stop = i<2;
    callback(stop);
}

function something2(i, callback) {
    var error = (i>2) ? new Error("poof") : null;
    callback(error);
}
Steven Vachon
  • 3,168
  • 1
  • 21
  • 29
0

I'm passing an object to differentiate between an error and just functionality. Which looks like:

function logAppStatus(status, cb){
  if(status == 'on'){
    console.log('app is on');
    cb(null, status);
  }
  else{
    cb({'status' : 'functionality', 'message': 'app is turned off'}) // <-- object 
  }
}

Later:

async.waterfall([
    getAppStatus,
    logAppStatus,
    checkStop
], function (error) {
    if (error) {
      if(error.status == 'error'){ // <-- if it's an actual error
        console.log(error.message);
      }
      else if(error.status == 'functionality'){ <-- if it's just functionality
        return
      }

    }
});
Anthony
  • 10,564
  • 12
  • 47
  • 65