【问题标题】:Async each function异步每个函数
【发布时间】:2017-01-28 11:04:31
【问题描述】:

我试图理解 async each(coll, iteratee, callback) 函数来为数组的每个项目并行执行一个函数。从异步文档中,我了解到回调只会执行一次(当迭代函数将为数组的每个项目执行时)。

并且在iteratee函数出错的情况下,调用callback('some error message')会立即调用带有错误信息的回调函数。

以下是每个函数的异步文档中的示例

每个(coll,iteratee,回调)

// assuming openFiles is an array of file names
async.each(openFiles, function(file, callback) {

    // Perform operation on file here.
    console.log('Processing file ' + file);

    if( file.length > 32 ) {
      console.log('This file name is too long');
      callback('File name too long');
    } else {
      // Do work to process file here
      console.log('File processed');
      callback();
    }
}, function(err) {
    // if any of the file processing produced an error, err would equal that error
    if( err ) {
      // One of the iterations produced an error.
      // All processing will now stop.
      console.log('A file failed to process');
    } else {
      console.log('All files have been processed successfully');
    }
});

我无法理解的是,不带参数调用 callback() 是做什么的,当 iteratee 函数中没有错误时,我们不带参数调用 callback() 对我来说看起来很奇怪。如果没有错误,调用callback() or callback(null) 会做什么。

我们不能只删除那些callback() or callback(null),而实际上我们的意思是只调用一次回调(当对数组的所有元素执行 iteratee 函数时)而不是对数组的每个项目。

【问题讨论】:

    标签: javascript asynchronous async.js


    【解决方案1】:

    在没有错误的情况下调用callback() or callback(null)会做什么。

    不带参数调用callback 或使用nullasync.each 发出信号,表明iteratee 函数已完成对该项目的执行(在示例中为file)。当所有iteratee 函数都调用了它们各自的callback,或者其中一个将错误传递给它的回调时,async.each 将调用传递给它的原始callback 函数。

    详细说明一下,async.js 旨在处理异步函数。异步函数的好处(或问题,取决于你如何看待它)是没有办法知道它何时会完成执行。处理这个问题的方法是向异步函数传递另一个函数callback,以便在完成时执行。异步函数可以通过callback 函数将它遇到的任何错误或它检索到的任何数据传递给原始调用函数。比如fs.readFile是通过callback函数将读取的文件数据传递过来的,任何错误都是通过的。

    我们不能只删除那些callback() or callback(null),而实际上我们的意思是只调用一次回调(当对数组的所有元素执行 iteratee 函数时)而不是对数组的每个项目。

    不,因为async.js 必须假设iteratee 函数是异步的,因此,它必须等待它到它的callback。传递给async.eachcallback 只被调用一次。

    混淆可能是由变量名引起的。一个单独的callback 函数只能被调用一次。传递给async.eachcallback 函数与传递给iterateecallback 不同。每次使用coll 中的值调用iteratee 时,都会传递一个新的callback 函数。 iteratee 的调用应该只调用传递的callback 一次(否则async 将抛出错误)。这允许async 跟踪对iteratee 函数的调用是否调用了它的callback,并等待其余调用它们各自的callback。一旦调用了所有callback 函数,async.each 就知道所有异步iteratee 函数调用都已完成执行,并且它可以调用传递给它的原始callback

    这是创建文档的难点之一。他们必须足够简洁,以便开发人员可以快速从他们那里获得信息,并且还必须包含足够的细节,以便他们可以解释概念或功能。有时很难达到平衡。

    【讨论】:

    • 谢谢@hargasinski,我有一个困惑,当我们在iteratee函数没有错误的情况下调用callback()时,看起来我们实际上是在执行回调函数(async.each的第三个参数)对于每个元素
    • 是的,我知道这有多令人困惑。您可以将参数重命名为 function(err, fileCallback) 之类的名称,然后调用 fileCallback();fileCallback('File name too long') 使其更清晰一些。在示例中,变量具有相同的名称但代表不同的事物。
    • 谢谢老哥,我明白了。
    • 不用担心,很高兴我能帮上忙。
    【解决方案2】:

    不带参数调用回调会添加到.each 函数内的计数器。这个计数器在满时是真正调用你的回调的东西。没有它,它永远不会知道它何时完成。

    【讨论】:

      猜你喜欢
      • 2013-07-25
      • 2015-07-08
      • 2019-01-07
      • 1970-01-01
      • 2018-11-21
      • 2021-12-05
      • 2019-02-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多