异步for循环:如何让for循环等待函数完成

Asynchronous for loop: how do I make the for loop wait for function to finish?

本文关键字:for 循环 函数 等待 异步      更新时间:2023-09-26

我绞尽脑汁想弄清楚如何对这个/地方回调进行排序以获得我需要的东西。

我有一个检查文件是否存在的循环。我希望它在完成时回调,但是for循环和回调在"fs"之前完成。打开"结束…典型的异步问题

我正在使用节点v0.10.29express v3.14.0,并且正在使用"async"库,但是再次,只是无法找出我需要的逻辑…

我有:

输入

function checkForAllFiles(callback)
{
    var requiredFiles = [];
    requiredFiles[requiredFiles.length] = "../Client/database/one.js";
    requiredFiles[requiredFiles.length] = "../Client/database/two.dat";
    requiredFiles[requiredFiles.length] = "../Client/database/three.xml";
    requiredFiles[requiredFiles.length] = "../Client/database/four.dat";
    requiredFiles[requiredFiles.length] = "../Client/database/five.dat";
    requiredFiles[requiredFiles.length] = "../Client/database/six.xml";
    var missingFiles = [];
    for(var r=0; r<requiredFiles.length; r++)
    {
        fs.open(requiredFiles[r], 'r', function(err, fd){
            if(err)
            {
                missingFiles[missingFiles.length] = err.path;
                console.log("found missing file = ", err.path);
            }
        });
        console.log("r = ", r);
    }
    console.log("sending callback: ", missingFiles);
    callback(missingFiles);
}
<标题> 输出
0
1
2
3
4
5
sending callback: []
found missing file: ../Client/database/three.xml
<标题>期望输出值
0
1
found missing file: ../Client/database/three.xml
2
3
4
5
sending callback: ["../Client/database/three.xml"]

我会在async模块中使用reject方法(我看到您已经找到了)。它将在回调函数中返回一个数组,其中包含与指定的检查函数不匹配的任何元素。对于检查功能,我建议只使用fs.exists,而不是监视fs.open上的错误。

使用这些函数实际上可以将整个检查减少到一行。像这样:

function checkForAllFiles(callback)
{
    var requiredFiles = [];
    requiredFiles[requiredFiles.length] = "../Client/database/one.js";
    requiredFiles[requiredFiles.length] = "../Client/database/two.dat";
    requiredFiles[requiredFiles.length] = "../Client/database/three.xml";
    requiredFiles[requiredFiles.length] = "../Client/database/four.dat";
    requiredFiles[requiredFiles.length] = "../Client/database/five.dat";
    requiredFiles[requiredFiles.length] = "../Client/database/six.xml";
    async.reject(requiredFiles, fs.exists, callback);
}

callback将使用一个数组调用,该数组只包含不存在的文件。

使用异步库和eachSeries方法。例子:

async.eachSeries(array,
     function(element, next) {
          // do something with element
          next();
     }
);

它将依次遍历数组并处理每个元素。调用next将转到下一个元素。Series确保它按照数组的顺序执行,否则不能保证遍历数组的顺序。如果你在其中调用了其他异步函数,只需传递下一个函数,并在完成所有需要的函数后调用它,下一个数组元素将被处理。

也许像这样:

var missingFiles = []
async.eachSeries(requiredFiles, function(file, nextFile){
 fs.open(file, 'r', function(err, fd){
        if(err)
        {
            missingFiles[missingFiles.length] = err.path;
            console.log("found missing file = ", err.path);
        }
       nextFile();
    });
    console.log("r = ", file);
});
console.log("sending callback: ", missingFiles);
callback(missingFiles);