itdeeps
itdeeps

Reputation: 277

Skip to main callback with result in async waterfall node js

Am new to node js and am working with async waterfall.

var methods = function (req, res) {
async.waterfall([
    func1(req, res),
    func2,
    func3
], mainCallback);
};

app.get("/create", function(request, response)
{
  methods(request, response);    
});

function func1 (something, res, callback) {
    if(something == 0)
    {
     callback (null, res, somethingelse);
    }
    else
    {
     mainCallback("success");
     }

}

function func2 (something, res, callback) {        
      callback (null, res, somethingmore);        
}

function func3 (something, res, callback) {
      callback (null, res, somethingmore);
}

function mainCallback (error, success)
{
 if (error)
{
    console.log("error");
}

if(success)
{
    //console.log("success");
}

}

In the above flow am able to skip to main call back with result but am not able to send more arguments to main call back.

For example If i want to send response from main call back then how can I send it as argument from func1?

I tried the following in func1 but it didn't work

mainCallback("success", response)

Please let me know how to skip methods func2 and func3. Also sending response as a argument to main allback.

Upvotes: 0

Views: 1488

Answers (2)

edin-m
edin-m

Reputation: 3121

Only way to skip rest of waterfall is to pass in err argument.

So calling: done({ something: { val: 1 }}) would skip rest of waterfall.

If it isn't really an error, you can put some object which you would parse in final callback, as not an error, but it will be passed as first argument in resulting callback (mainCallback).

function func1 (something, res, callback) {
    if (something == 0) {
        callback (null, res, somethingelse);
    } else {
        callback({val:1});
    }
}

EDIT

But yes, you should not use error as way to control flow or break out of async. It should be used only for propagating errors.

Upvotes: 0

nvartolomei
nvartolomei

Reputation: 1505

Do not use return/throwing errors to control execution flow, it's a code smell.

Instead refactor the code as follows:

function mainCallback(err, res) {
    if (err) {
        console.log(err);
    } else {
        console.log(res);
    }
}

function routeHandler(req, res) {
    func1(req, res, function(err, res) {
        if (res.something === 0) {
            async.waterfall([
                func2,
                func3
            ], mainCallback)
        } else {
            mainCallback(null, 'success')
        }
    })
}

app.get('/create', routeHandler());

Notice that when calling mainCallback I pass first value as null, this is done to respect error contract, so when mainCallback is called and first argument has a value then I know for sure it is an error, otherwise second parameter should contain result.

Also this will make your code more readable and easier to understand, you have explicitly an if branch in func1.

I would suggest to read this too: http://fredkschott.com/post/2014/03/understanding-error-first-callbacks-in-node-js/

Upvotes: 3

Related Questions