如何等待 fs.readFile?

fij*_*iji 3 node.js

我在等待时遇到问题,fs.readFile() 我有一个文件,我想在其中迭代每一行,并将非重复的内容保存在 array 内domains

但是,当我用它调用我的函数fs.readFile时,我调用的console.log(domains)域是空的。

代码

var fs = require("fs");
var re = /@(.*?):/;
let domains = [];

const parseProviders = () => {
    fs.readFile("file.txt", (error, data) => {
    if (error) throw error;
    data
      .toString()
      .split("\n")
      .forEach((line, index, arr) => {
        try {
          line = line.match(re)[1];
          if(!domains.includes(line)) {
            domains.push(line);
          }
        } catch (err) {
          throw err;  
        }
      });
      console.log(domains); // this would work and print an array with non-duplicate items
  });
}

(() => {
  parseProviders();
  console.log(domains); // prints an empty array []
})();
Run Code Online (Sandbox Code Playgroud)

Ben*_*ght 8

您可以在这里做很多不同的事情。(请注意,在下面的代码示例中,我故意简化了内容以使它们更易于阅读)您可以

1. 修改您的函数以采用由 readfile 回调执行的回调

const parseProviders = (callback) => {
    fs.readFile("file.txt", (error, data) => {
      data
        .toString()
        .split('\n')
        .forEach(line => domains.push(line))
    });
  });
}

(() => {
  parseProviders(() => {
    console.log(domains);
  });
})();
Run Code Online (Sandbox Code Playgroud)

fs/promises2.按照@robertklep 在评论中的建议使用该模块。如果你这样做,你应该把它变成一个异步函数

const  { readFile } = require("fs/promises")

const parseProviders = async (callback) => {
    const data = await readFile("file.txt")
    data
      .toString()
      .split('\n')
      .forEach(line => domains.push(line))
  });
}

(async () => {
  await parseProviders()
  console.log(domains);
})();
Run Code Online (Sandbox Code Playgroud)

3. 手动promise readFile 函数。

const parseProviders = () => {
    return new Promise((accept, reject) => {
      fs.readFile("file.txt", (error, data) => {
      data
        .toString()
        .split('\n')
        .forEach(line => domains.push(line))
        accept();
      });
  });
}

(async () => {
  await parseProviders()
  console.log(domains);
})();
Run Code Online (Sandbox Code Playgroud)
  • 注意 - 您不需要执行此操作,但在处理其他回调样式 API 时,了解如何执行此操作是值得的。