异步 - 回调不是函数

时间:2016-10-26 18:24:33

标签: javascript node.js asynchronous

我正在尝试在节点js中使用异步,以控制某些函数的执行流程。在下面的代码中,我有三个声明的函数,分别打印'one','two'和'three',以及执行其他任务(打印只是为了让我可以看到什么时候执行)。

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');
    }
  ]);

所以我在回调(null,'two')行中得到错误“回调不是函数”; 说实话,这可能是一个非常虚拟的问题,我不完全理解异步瀑布的工作原理。但我认真地尝试通过阅读示例尝试实现短代码并尝试使用它。

有趣的是,如果使用async.series而不是async.waterfall,则没有这样的错误。但是,async.series将打印1,2,3,3,1,2。 瀑布模型中的数字按顺序打印,但内部函数不按正确顺序执行。

需要注意的是,前两个函数 - 设置和配置文件 - 包括数据库读取和计算,而第三个只打印一些结果。

5 个答案:

答案 0 :(得分:4)

为简化起见,callback(null, 'one')表示您将一个参数传递给下一个。这意味着你的函数需要在回调前接受1个参数。

callback(null, 'one')跟在function(arg1, callback) arg1 = 'one'

之后

callback(null, 'one', 'two')跟在function(arg1, arg2, callback)arg1='one'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');
    }
  ]);

答案 1 :(得分:3)

使用async.waterfall,结果将作为参数传递给下一个函数。例如:

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'
});

在您的情况下,第二个函数上的callback将收到字符串one作为参数。因此,您遇到的错误。

答案 2 :(得分:2)

瀑布

首先我建议你使用Async auto代替瀑布模型这背后的原因是在瀑布模型中我们将逐个移动,我们将完成第一个功能的执行然后继续到第二个然后第三个即我们将进入一系列无论天气我们的功能是否相互依赖

自动

auto的好处是,天气你的功能依赖于彼此并不重要,因为auto可以串行(对于依赖函数)和并行(对于不依赖于彼此的函数)运行任务

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) {

});

在上面的示例中,我们有get_Data函数和make_folder函数,它们彼此不相关,因此我们可以并行运行它们并传递get_Data和amp;的名称。 make_folder我们可以限制write_file函数只有在上述两个函数都被执行后才能运行。

有关详细信息,请访问http://caolan.github.io/async/docs.html#auto

甚至看看 async.autoInject 它最近被添加到异步代替auto。但是auto会继续使用珍贵版本的async

答案 3 :(得分:1)

  

这不是使用waterfall尝试在函数中传递其他参数并将最后一个参数作为回调使用的正确方法。

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

你也忘了在所有执行完毕后传递最终回调。

答案 4 :(得分:0)

异步瀑布回调和方法的顺序应该匹配才能正常工作。由于方法错误,我遇到了同样的问题。您的回调参数和下一个函数的参数应匹配才能正常工作。请参考以下示例。

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

在async.waterfall数组中,您可以指定方法的顺序。请参阅documentation以获取更多示例。