node async waterfall使用带有带参数的回调的数组

时间:2013-12-23 18:42:30

标签: javascript node.js asynchronous waterfall

我收到一个我不明白的错误。我用一系列函数调用async.waterfall。为清晰起见,该功能已“缩短”。

FabricCommand.prototype.do = function (callback, undoArray) {
    var self = this;

    if (undoArray === undefined) {
        undoArray = [];
    }

    undoArray.push(self);
    callback(null, undoArray);
};

我创建了如下所列的数组:doCommands是一个数组,对象是这样添加的:

doCommands.push(fabricCommand.do.bind(fabricCommand));

瀑布设置:

async.waterfall(
    doCommands,
    function(err, undoCommands){
        if (err) {
           // do something ...
        }
        else {
            console.log('we succeeded with all the do commands... and there are '
                + undoCommands.length
                + ' in the undoCommands but we will disregard it...');
        }
    }
);

现在当我运行这段代码时,第一次通过FabricCommand.do函数,我分配了undoCommands数组并向其添加了一个,下次通过我得到,我尝试添加数组元素,出现以下错误:

undoArray.push(something);
          ^ TypeError: Object 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);
                });
            }
        } has no method 'push'

谁能看到我做错了什么?

1 个答案:

答案 0 :(得分:2)

async.waterfall执行的功能必须具有以下签名:

function(arg, callback) { … }

或者,有多个参数:

function(arg1, arg2, callback) { … }

在您的情况下,您只需将两个参数反转:

 FabricCommand.prototype.do = function (callback, undoArray) { … }

callback收到了要存储在undoArray中的值,undoArray收到了callback的值,即一个函数:这就是你遇到这个奇怪的原因错误(function […] has no method 'push')。

您需要按正确顺序放置参数:

 FabricCommand.prototype.do = function (undoArray, callback) { … }

第二个问题是瀑布的第一个函数只接收一个参数:回调(因为没有要接收的值,因为它是瀑布的第一个函数)。解决方案是检查参数的数量:

if (Array.prototype.slice.apply(arguments).length === 1) {
    callback = undoArray;
    undoArray = undefined;
}

这是working gist