2016-10-26 146 views
1

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

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,“两节”); 说实话,这可能是一个非常虚拟的问题,我不完全理解异步瀑布是如何工作的。但是我认真地尝试了一下,通过阅读例子,试图实现短代码并试着玩弄它。

有趣的是,如果使用async.series代替async.waterfall,则不会出现此类错误。但是,async.series将打印1,2,3,三,一,二。 瀑布模型中的数字按顺序打印,但里面的函数不按正确的顺序执行。

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

+0

的珍贵版本,特别是如果你调用'async.series'的'async.waterfall',反之亦然,'async'内部出现此问题,当你窝'async'电话,将变得不可靠。 – Sandwich

回答

2

随着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作为参数。因此,你正在经历的错误。

3

为了简化起见,callback(null, 'one')表示您将一个参数传递给next。含义你的功能需要在回调前接受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

这是不使用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)}); 

你也忘记了所有的执行后通过最终回调。

2

瀑布

所有我建议你使用异步自动到位瀑布模型背后的原因是在瀑布模型首先我们将通过一个移动一个像第一,我们将完成第一个函数的执行,然后继续前进到第二和第三。Ë我们将在一系列不事项经得起我们的功能都依赖于这种相互与否

自动

汽车的好处是,它并没有真正重要的天气你的功能都依赖于对方为汽车能运行一系列任务(对于相关的函数)和平行(为其不依赖于彼此的功能)

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 & ma ke_folder我们可以限制write_file函数只有在执行上面的两个函数之后才能运行。

了解更多详情,您可以访问http://caolan.github.io/async/docs.html#auto

甚至一看就async.autoInject它最近被添加的,地方汽车的非同步的。但汽车将继续为异步

+0

虽然我有一个问题。下一个函数是否等待前一个函数完成执行?或者我必须自己处理这个问题? –

+0

肯定它确实@Freya像例子中,我已经给我们有一个WRITE_FILE功能,将等待“GET_DATA”,“make_folder”当他们两人得到执行,然后只将WRITE_FILE得到执行第一次完整。 –

+0

我发现答案很有帮助,谢谢。因此,upvote。但这不是唯一有用的答案,实际上并没有针对具体的问题。来这里遇到类似问题的人想知道回调是如何工作的,而不是在不同场景中使用的异步类型,或者.waterfall和.auto之间的区别。 –