Is there a way to stop execution of next function of series with async in nodejs?
Asked Answered
Q

4

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"?

Quadratic answered 7/5, 2013 at 15:55 Comment(2)
return callback('stop') will stop the execution of your series and call async callback function with err = 'stop'.Doubtful
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.Quadratic
P
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

Platinum answered 7/5, 2013 at 16:2 Comment(4)
When you say callback with false, but the callback(true)... how is that false?Quadratic
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. SorryPlatinum
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.Rafter
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. github.com/caolan/async#seriesPlatinum
C
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.

Cinerator answered 21/1, 2015 at 12:10 Comment(0)
S
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);
}
Salvo answered 8/6, 2014 at 20:40 Comment(0)
P
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
      }

    }
});
Protractor answered 10/6, 2015 at 21:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.