callback is not a function

I am trying to work with async in node js, to control the flow of execution of some functions. In the code below I have three declared functions that should print respectively 'one', 'two' and 'three', along with performing other tasks (the printing is only so that I can see what gets executed when).

async.waterfall([
    function(callback) {
      settings();
      console.log("1");
      callback(null, 'one');
    },
    function(callback) {
      profile();
      console.log("2");
      callback(null, 'two');
    },
    function(callback) {
        console.log("3");
        groups();
        callback(null, 'two');
    }
  ]);

So I get the error "callback is not a function" in the line of callback(null, 'two'); To be honest, this might as well be a very dummy question, and I do not fully understand how async waterfall works. But I seriously did try, by reading examples, trying to implement short code and trying to play around with it.

Interesting that if async.series is used instead of async.waterfall, there is no such error. However async.series will print 1, 2, 3, three, one, two. The numbers inside the waterfall model are printed in sequence, but the functions inside are not executed in the right order.

It is to be noted that the first two functions - settings and profile - include db reading and calculations whereas the third only prints some results.


With async.waterfall , results are passed to the next function as arguments. For example:

async.waterfall([
    function(callback) {
        callback(null, 'one', 'two');
    },
    function(arg1, arg2, callback) {
        // arg1 now equals 'one' and arg2 now equals 'two'
        callback(null, 'three');
    },
    function(arg1, callback) {
        // arg1 now equals 'three'
        callback(null, 'done');
    }
], function (err, result) {
    // result now equals 'done'
});

In your case, callback on the second function will have received the string one as argument. And thus the error you are experiencing.


To make it simplified, callback(null, 'one') means you pass one argument to next. Meaning your function need to accept 1 parameter in front of callback.

callback(null, 'one') follows by function(arg1, callback) where arg1 = 'one'

callback(null, 'one', 'two') follows by function(arg1, arg2, callback) where arg1='one' and arg2='two'

async.waterfall([
    function(callback) {
      settings();
      console.log("1");
      callback(null, 'one');
    },
    function(arg1, callback) {
      profile();
      console.log("2");
      callback(null, 'two');
    },
    function(arg1, callback) {
        console.log("3");
        groups();
        callback(null, 'two');
    }
  ]);

Waterfall

First of all I advice you to use Async auto in place of waterfall model the reason behind this is in waterfall model we will be moving one by one like first we will finish the execution of 1st function then move on to second then 3rd ie we will go in a series no matters weather our function are dependent on each other or not

Auto

Benefits of auto are that it doesn't really matters weather your functions are dependent on each other as auto can run tasks in series (for dependent functions) and parallel (for the functions which are not dependent on each other)

async.auto({
    get_data: function(callback) {
        console.log('in get_data');

        callback(null);
    },
    make_folder: function(callback) {

        callback(null);
    },
    write_file: ['get_data', 'make_folder', function(results, callback) {

        callback(null);
    }],
    email_link: ['write_file', function(results, callback) {

        callback(null);
    }]
}, function(err, results) {

});

here in above example we have get_Data function and make_folder function which are not dependent on each other so we can run them parallel and by passing the name of get_Data & make_folder we can restrict out write_file function to run only after both of above function get executed.

for more details you can visit http://caolan.github.io/async/docs.html#auto

even have a look on async.autoInject it have recently been added to async in place of auto. but auto will continue for precious versions of async

链接地址: http://www.djcxy.com/p/55490.html

上一篇: 使用.join()调用异步承诺内的异步承诺

下一篇: 回调不是一个函数