waterfall中的callback为什么没有执行?
发布于 5个月前 作者 yakczh 479 次浏览 来自 问答

var async=require('async');

var log=console.log;
var callback=function (err,args){
args++;

log("args:"+args);
}
async.waterfall([
    function(callback){
        log("start");

        callback(null,100);
    },
    function(err, callback){
     
        log( err);

        callback(null   , 200);
    },
    function(err, callback){
   
        log( err);
        callback(null, 300);
    }
], function (err, result) {
   // result now equals 'done'
        log(result);
    log("done");


});
9 回复

看不懂你的代码。 外层的 callback 会被覆盖掉的,在 waterfall 里面的 function 中,都读不到。

而且你这个 waterfall 的用法跟官方的例子完全不同啊。官方没有那么多的 function (err, callback),带 err 参数的函数只有最终的那个。

带 err 参数的函数只有最终的那个 顶这个答案

改了一下

var async=require('async');

var log=console.log;
var inc=function (args,callback){
    args++;
 callback(null, args);

log("inc args:"+args);

}
async.waterfall([function(callback){
        log("start");

        callback(null,100);
    },
    function(args, callback){

        log( args);

        inc(args, callback);
    },
    function(args, callback){

        log( args);
       inc(args, callback);
    }
], function (err, result) {

        log("err:"+err);
        log("result:"+result);
    log("done");


});

貌似这里面的callback不是一个实际的函数,只是一个占位符一样的东西,根据执行结果看,好象最终的那个function (err, result)执行以后,inc还会执行一次,是waterfall本来是这样,还是代码有问题?

@yakczh 输出结果是怎样的

@yakczh QQ截图20140911140819.png 运行没有问题,在最后一个inc打印之前已经调用callback,在callback(null, args);没跑完前是不会继续下面的日志输出

@karlsun
运行结果 start 100 inc args:101 101 err:null result:102 done inc args:102

@karlsun
按代码的顺序应该是 done是最后,实际上 inc args102 最后

@yakczh 顺序没错,如果想inc args:102打印在前,必须在callback之前,最后的fuction(err, result)...内的打印语句并不是异步执行,所以在这个function执行完成后才打印。

    async.waterfall = function (tasks, callback) {
        callback = callback || function () {};
        if (!_isArray(tasks)) {
          var err = new Error('First argument to waterfall must be an array of functions');
          return callback(err);
        }
        if (!tasks.length) {
            return callback();
        }
        var wrapIterator = function (iterator) {
            return function (err) {
                if (err) {
                    callback.apply(null, arguments);
                    callback = function () {};
                }
                else {
                    var args = Array.prototype.slice.call(arguments, 1);
                    var next = iterator.next();
                    if (next) {
                        args.push(wrapIterator(next));
                    }
                    else {
                        args.push(callback);
                    }
                    async.setImmediate(function () {
                        iterator.apply(null, args);
                    });
                }
            };
        };
        wrapIterator(async.iterator(tasks))();
    };

这是async.waterfall源码,并没有异步调用callback.

回到顶部