【问题标题】:How do I wait for multiple fs.readFile calls?如何等待多个 fs.readFile 调用?
【发布时间】:2019-05-18 19:51:17
【问题描述】:

我的目标是从两个文件中读取数据并比较数据。我的输入文件是result3.json和result4.json。这些文件中的数据是逗号分隔的。

result3.json

[
  "temp1.txt",
  "temp2.txt",
]

节点:

function readFromFile(file) {
    var fileNames = [];
    //setTimeout(function() {
        fs.readFile(file,function(err, data){
            if (err) {
                return console.log(err);
            }
            var temp = JSON.parse(data.toString().split(","));
            // console.log(temp.length);
            for (let index = 0; index < temp.length; index++) {
                //console.log(temp[index]);
                fileNames.push(temp[index]);
                //console.log(fileNames[index]);
            }
            Done(); // to block the async call
        });
        //},3000);
    //console.log(fileNames.length);
    return fileNames;
}

var baseListOfFiles = readFromFile('./output/result3.json'); // Assume this is the base file
var currentListOfFiles = readFromFile('./output/result4.json'); // Assume this is the current file

function Done(){
    //console.log('Out baseListOfFiles + ' + baseListOfFiles.length);
    for (let index = 0; index < baseListOfFiles.length; index++) {
        console.log("[baseListOfFiles] " + baseListOfFiles[index]);
    }

    //console.log('Out currentListOfFiles+ ' + currentListOfFiles.length);
    for (let index = 0; index < currentListOfFiles.length; index++) {
        console.log("[currentListOfFiles] " + currentListOfFiles[index]);
    }

}

以上是我的代码。它似乎是异步调用,所以它总是返回 0 个文件名。 有什么办法控制吗?

【问题讨论】:

  • 有几种方法可以等待多个异步调用完成。请参阅此处:stackoverflow.com/questions/31413749/… 此外,如果这些文件包含 JSON,则无需使用 toString()split() 或其中任何一个。

标签: javascript node.js


【解决方案1】:

这是使用 Promises 的示例代码:

const fs = require('fs');

function readFromFile(file) {
    return new Promise((resolve, reject) => {
        fs.readFile(file, function (err, data) {
            if (err) {
                console.log(err);
                reject(err);
            }
            else {
                resolve(JSON.parse(data));
            }
        });
    });
}

const promises = [
    readFromFile('./output/result3.json'),
    readFromFile('./output/result4.json')
];

Promise.all(promises).then(result => {
    console.log(result);
    baseListOfFiles = result[0];
    currentListOfFiles = result[1];
    // do more stuff
});

首先,构建一个数组promises;每个 Promise 都会读取文件,然后调用 resolve 并返回结果。
这个数组被传递给Promise.all()then 调用回调,以相同的顺序传递结果数组。

【讨论】:

    【解决方案2】:

    你说得对,readFile 是异步的。你要找的是readFileSync:https://nodejs.org/api/fs.html#fs_fs_readfilesync_path_options

    有了这个可以做:

    const data = fs.readFileSync(file);
    
    //do something with data
    

    如果您愿意,有几种“承诺”readFile 的方法,这里讨论了这些选项:Using filesystem in node.js with async / await

    【讨论】:

    • 感谢您的指导。我会试试这个方法
    • @PraveerKumar 使用util.promisifyfs.readFile() 包装成一个promise,然后使用async 和await,如果你使用的是>= NodeJS v8。
    • 实际上应该是另一个答案。 JS本质上是异步的,强制同步不是一个好主意。想象一下,两者读取文件都需要 1 分钟,您不想等待 1+1= 2 分钟,而是只等待 1 分钟,因为两者都已并行完成
    猜你喜欢
    • 1970-01-01
    • 2021-08-14
    • 1970-01-01
    • 1970-01-01
    • 2017-12-15
    • 2013-11-23
    • 2013-08-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多