我正在尝试使用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到底包含什么?

最佳答案

作为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不会执行下一次迭代,直到以cb()分辨率调用setTimeout为止。如果在函数终止后whilst运行了下一个迭代,则所有setTimeout调用将同时排队,而不是一个接一个地运行。而是等到函数调用cb()为止。

由于您从不会在代码中调用cb(),因此whilst只是假设该函数已调度了一个耗时很长的异步任务。 whilst将不会运行下一个迭代,直到第一个函数调用通过调用cb()确认已完成。

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

10-06 11:55