【问题标题】:Inner block of a code is getting executed after the first block in node js在节点 js 中的第一个块之后执行代码的内部块
【发布时间】:2021-11-24 02:30:35
【问题描述】:

根据这个“1”要先打印,然后再打印“2”。但是它给出了错误的输出。

fs.readdir("./my_stocks", (err, files) => {
    for(each in files){
        var file=files[each];
        if(file!='portfolio.js'){
            var fn="./my_stocks/"+file;
            fs.readFile(fn,(err,data)=>{
                var arr=data.toString().split('\n');
                console.log(1);
                fs.appendFile("./my_stocks/portfolio.js",JSON.stringify(stock_detail),(err)=>{
                    if(err) throw err;
                });
            });
            console.log(2)
        }
    }
});

输出:

2 2 1 1

【问题讨论】:

    标签: javascript node.js express


    【解决方案1】:

    “内部块”是对fs.readFile 语句的回调。会发生什么

    1. fs.readFile 被执行并开始异步读取文件。
    2. 执行下一条语句,输出“2”。
    3. 对目录中的每个文件都重复步骤 1 和 2,这样一共输出了两个“2”。
    4. 稍后,当一个文件的读取完成后,执行“内块”,输出一个“1”。
    5. 因为一共读取了两个文件,所以步骤 4 执行了两次并输出了两个“1”。但输出的第一个“1”不一定属于正在读取的第一个文件,因为较短的文件可能在较长的文件之前完成读取,即使它稍后开始。

    如果你想避免这种异步,你可以使用fs.readFileSync(也可以使用fs.readdirSync)。但这会减慢整体执行速度,因为文件会一个接一个地读取,而不是并行读取。如果您的portfolio.js 中的条目顺序无关紧要,那么异步是更可取的。

    但是请注意,将多个 stock_details 附加到一个 portfolio.js 并不能生成有效的 Javascript:

    {"Stock 1":100}{"Stock 2":200}
    

    假设每个文件都包含如下行

    A: 1
    B: 2
    

    (没有最后的换行符),您可以使用 fs 包的“promises flavor”异步读取和处理它们:

    const fs = require("fs/promises");
    fs.readdir("./my_stocks")
    .then(function(files) {
      var promises = [];
      for(each in files){
        var file=files[each];
        if(file!='portfolio.js'){
          var fn="./my_stocks/"+file;
          promises.push(fs.readFile(fn)
            .then(data => data.toString().split('\n')));
        }
      }
      return Promise.all(promises);
    })
    .then(portfolio => fs.writeFile("./my_stocks/portfolio.js", JSON.stringify(portfolio)));
    

    【讨论】:

    • 我正在尝试制作一个 json 文件,其中包含 ./my_stock/ 中所有与股票相关的文件的详细信息。所以我每次执行它时都会得到一个空文件。 fs.readFileSync() 是一个好习惯吗? @Heiko
    • 同步执行不是好的做法(对于大文件),因为它会阻塞 Javascript 线程。有关使用异步执行的解决方案,请参阅我编辑的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-03
    • 1970-01-01
    • 2021-02-05
    • 1970-01-01
    • 1970-01-01
    • 2020-03-10
    • 1970-01-01
    相关资源
    最近更新 更多