electron 同步性问题:等待多个fs.readFile调用完成

iyr7buue  于 2023-01-22  发布在  Electron
关注(0)|答案(2)|浏览(366)

我想从不同的CSV文件中读取列,并将这些列组合成一个数组。我使用fs.readFile读取CSV文件,回调函数处理数据并将新元素推送到列数组中。然后,列数组被发送到软件的另一部分(我正在构建一个电子应用程序,因此它被发送到渲染过程)。
我遇到的问题是,“fs.readFile”是异步的,因此我的columns数组在任何fs.readFile调用完成之前就被发送出去了,导致数组为空。
解决这个问题的最好方法是什么?是简单地使用fs.readFileSync吗?有没有一种方法可以做到这一点而不阻塞执行?
最小示例代码如下:

//Process each column, reading the file and extracting the data one at a time
let columns: (number[] | undefined)[] = []; //Somewhere to store the processed columns
for (const dataHandle of dataHandles)
{
  //read the file as a raw string
  fs.readFile(dataHandle.filePath, (error: any, data: any) => {
    if (error) {
      console.log("Error reading file:", error);
    } else {
      data = data.toString();
      const newColumn = parseColumnFromStringDataframe(data, dataHandle.columnName);
      columns.push(newColumn);
    }
  })
}
//Finished processing each column, so send response.
//BUT... readfile is non-blocking! Sends the response before anything is pushed to columns! How can we wait in a smart way?
console.log(columns); // []
mainWindow?.webContents.send("readDataProductColumnsResponse", columns); //Sends response
ct2axkht

ct2axkht1#

这是回答这里:https://stackoverflow.com/a/34642827/7603434
基本上,您必须创建一个promise数组,然后调用Promise.all(promises);

const fs = require("fs");
const files = ["app.js", "index.html", "script.js"];

const readAllFiles = async () => {
  let promises = [];
  for (const f of files) {
    promises.push(fs.promises.readFile(f, "utf8"));
  }
  return Promise.all(promises);
};

async function run() {
  readAllFiles()
    .then((fileContents) => {
      console.log("done", fileContents);
      // fileContents is an array that contains all the file contents as strings
    })
    .catch((err) => {
      console.error(err);
    });
}

run();
kxxlusnw

kxxlusnw2#

更紧凑的解决方案是

const fs = require("fs").promises;
const files = ["aaa.txt", "bbb.txt"];

(async () => {
  Promise.all(files.map((file) => fs.readFile(file, "utf8")))
    .then((data) => {
      console.log(data);    // ['content of aaa', 'content of bbb']
    })
    .catch((err) => {
      console.error(err);
    });
})();

相关问题