async.whilst 中的回调和错误是做啥用的?

Posted

技术标签:

【中文标题】async.whilst 中的回调和错误是做啥用的?【英文标题】:What is the callback and err in async.whilst used for?async.whilst 中的回调和错误是做什么用的? 【发布时间】:2015-07-10 06:26:48 【问题描述】:

我正在尝试使用 async.whilst 重新生成一个介于 0 和数组长度之间的随机数,直到该索引上的元素长度大于指定长度。我想为此使用 async.whilst,但语法对我来说并不完全清楚。我想过做以下事情:

var selectParagraph = function(paragraphs, callback)
    var index = Math.floor(Math.random() * paragraphs.length
    async.whilst(
        function() 
            return paragraphs[index].length < minParagraphLength; 
        ,
        function(cb) 
            index = Math.floor(Math.random() * paragraphs.length);
        ,
        function(err) 
            console.log(paragraphs[index]);
            callback(err, paragraphs[index]);
        
    

但是,这不起作用。我想这是因为我没有在任何地方将 cb 用于第二个功能,但我不完全知道应该如何使用它。我只是在更改索引后调用 cb() 吗?变量 err 究竟包含什么?

【问题讨论】:

为什么不在这里使用普通的while 循环?您似乎没有进行任何异步调用。 我必须在 while 循环完成后执行回调。回调不会在正常的while循环完成之前发生吗?为了清楚起见,我将在代码示例中添加回调。 像这样的while 循环是同步的(它不依赖于任何异步操作),因此您可以在完成后调用您的回调。 @Eva:为什么必须执行回调?您的函数不执行任何异步操作,因此它不需要进行回调。 这个while循环是在main函数中调用的函数中执行的,所以我需要执行一个包含所选索引到main函数的回调。 【参考方案1】:

我想是因为我没有在任何地方使用第二个函数的回调

是的,没错。 async.js 希望您在完成后回电,如果您不回电,则不会继续下一次迭代。

但我不完全知道我应该如何使用它

你根本不应该使用它,因为你没有做任何异步操作。使用标准的do while 循环:

do 
    var index = Math.floor(Math.random() * paragraphs.length); 
 while (paragraphs[index].length < minParagraphLength)
console.log(paragraphs[index]);

callback(null, paragraphs[index]); // not sure where you're getting `callback` from

【讨论】:

谢谢,正常的 do while 循环确实有效,我认为这不会。回调是必要的,因为此循环包含在一个函数中,我在原始问题中对其进行了编辑。您能否解释一下 async.whilst 参数中的 cb 和 err 到底是什么?这样,我可以在必要时使用它们。【参考方案2】:

作为Bergi has already noted,您没有做任何异步操作,也根本不需要使用whilst。不过,我将进一步解决您对 whilst 工作原理的具体困惑。

whilst 的第二个参数是一个可以执行异步操作的函数。 whilst 无法知道该功能何时“完成”了它需要做的所有事情。回调参数是一种向whilst 发送信号的方式,该函数已完全完成其所有任务,whilst 可以继续下一次迭代。

假设我们想要每隔一秒制作一个系列控制台消息。 (这是一个非常人为的例子,但我想不出一个更容易解释的自然例子。)

var i = 0;
async.whilst(
    function() return i < 5; ,

    function(cb) 
        setTimeout(function() 
            console.log(i++);
            cb();
        , 1000);
    ,

    function(err)  console.err("we encountered an error", err); 
);

在这种情况下,我们调用setTimeout,然后whilst 不会执行下一次迭代,直到在setTimeout 分辨率中调用cb()。如果whilst 在函数终止后立即运行下一次迭代,则所有setTimeout 调用将同时排队,而不是一个接一个地运行。相反,它一直等到函数调用cb()

由于您从未在代码中调用cb()whilst 只是假设该函数已分派了一个需要很长时间的异步任务。 whilst 不会运行下一次迭代,直到第一个函数调用通过调用 cb() 确认它已完成。

cb() 的不带参数调用表明该函数已顺利完成其任务。如果函数以错误结束(无法读取文件,无法访问网络资源),那么您可以将该错误作为参数提供给cb(例如cb(new Error("could not reach the server"));),该错误将提供给whilst 的第三个函数参数。

【讨论】:

非常感谢。我只是在 async.whilst 之后添加剩余的突击队员,还是像使用 async.each 等一样将它们添加到 function(err) 中? @Eva:是的。在 whilst 循环完成后,您想要异步执行的所有内容都需要进入回调。 我使用相同的格式,但从 v3 开始,这种使用 while 的方式发生了变化

以上是关于async.whilst 中的回调和错误是做啥用的?的主要内容,如果未能解决你的问题,请参考以下文章

TTF/OTF 头表中的 checkSumAdjustment 是做啥用的?

SetPixelFormat() 中的 PIXELFORMATDESCRIPTOR 参数是做啥用的?

Laravel 中的 `HtmlString` 是做啥用的?

python中的StringIO在现实中是做啥用的?

linux 中的xinetd是做啥用的?

Visual Studio 中的“stdafx.h”是做啥用的?