Javascript 使用具有参数的回调的数组的节点异步瀑布

Javascript 使用具有参数的回调的数组的节点异步瀑布,javascript,node.js,asynchronous,waterfall,Javascript,Node.js,Asynchronous,Waterfall,我犯了一个我不明白的错误。我使用一系列函数调用async.瀑布。为清晰起见,该功能被“缩短” FabricCommand.prototype.do = function (callback, undoArray) { var self = this; if (undoArray === undefined) { undoArray = []; } undoArray.push(self); callback(null, undoArra

我犯了一个我不明白的错误。我使用一系列函数调用async.瀑布。为清晰起见,该功能被“缩短”

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数组并向其中添加一个,下一次通过get尝试添加数组元素时,出现以下错误:

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'

有人知道我做错了什么吗?

执行的函数必须具有以下签名:

function(arg, callback) { … }
或者,使用多个参数:

function(arg1, arg2, callback) { … }
if (Array.prototype.slice.apply(arguments).length === 1) {
    callback = undoArray;
    undoArray = undefined;
}
在您的例子中,您只需反转两个参数:

 FabricCommand.prototype.do = function (callback, undoArray) { … }
callback
收到了要存储在
undoArray
中的值,
undoArray
收到了要存储在
callback
中的值,即函数:这就是您遇到此奇怪错误的原因(
函数[…]没有方法“推送”

您需要将参数按正确的顺序排列:

 FabricCommand.prototype.do = function (undoArray, callback) { … }
第二个问题是瀑布的第一个函数只接收一个参数:回调(因为没有要接收的值,因为它是瀑布的第一个函数)。解决方案是检查参数的数量:

function(arg1, arg2, callback) { … }
if (Array.prototype.slice.apply(arguments).length === 1) {
    callback = undoArray;
    undoArray = undefined;
}

这是一个。

谢谢,我是否仍然保留回调(null,undoArray);按原样或调用必须反转参数?是的,这是正确的。第一个参数是错误(不为null,
async
将停止瀑布并立即调用最后一个回调),第二个参数是结果,它将传递给瀑布中的下一个函数。当我将函数签名更改为…do=function时(undoArray,callback,在第一次调用中,我查看了undoArray is function(err)的值,与之前的错误相同,但我在第一次调用中得到的错误可能是绑定有问题?另一个问题是瀑布的第一个函数只有一个参数:回调。让我编辑我的答案。