简体   繁体   English

NodeJS - 等到流式传输多个文件完成后再继续编写代码

[英]NodeJS - Wait Until Streaming Multiple Files Is Complete Before Continuing Code

I'm new to Javascript and NodeJS.我是 Javascript 和 NodeJS 的新手。 Im trying to read multiple CSV files before doing some processing on them.我试图在对它们进行一些处理之前读取多个 CSV 文件。 My current issue is when I run the code it tries to execute the processing before the reading of the file is complete.我当前的问题是,当我运行代码时,它会在文件读取完成之前尝试执行处理。 I would like to load both the CSVs before I start doing any processing on them.我想在开始对它们进行任何处理之前加载这两个 CSV。

Could some explain why this happens and how I can solve the problem in Javascript/NodeJS.有人可以解释为什么会发生这种情况以及我如何解决 Javascript/NodeJS 中的问题。

function readCSV(path){

    var events = []
    
    fs.createReadStream(path).pipe(csv()).on('data', (row) => {
        events.push(row);
    }).on('end', () => {
        console.log('CSV file successfully processed. Length: ' + events.length);
    }); 

    return events
}

function app(){

    var file_list = listFiles(folder_path);

    for (let i = 0; i < file_list.length; i++) {
        const file = file_list[i];
        var events = readCSV(file)
    }
    
    processCSV(events) // Some processing
}

app();

Any help would be great and any explanation on how I can control when code is executed would be much appreciated.任何帮助都会很好,任何关于我如何控制代码何时执行的解释都将不胜感激。

Sorry, your code cannot be compiled, so I can answer only with untested code.抱歉,您的代码无法编译,所以我只能用未经测试的代码来回答。

My current issue is when I run the code it tries to execute the processing before the reading of the file is complete.我当前的问题是,当我运行代码时,它会在文件读取完成之前尝试执行处理。

The main problem is that fs.createReadStream doesn't read the file, it requests the file system to start reading and calls your callbacks when some chunks were read, so event 'end' will be called much later, after readCSV completed and returned an empty result.主要问题是fs.createReadStream不读取文件,它请求文件系统开始读取并在读取一些块时调用您的回调,因此事件 'end' 将在readCSV完成并返回一个之后被调用很久空结果。

Your code was written as if you expect an synchronous answer, and you can make it work correctly with the use of sync methods like fs.readFileSync .您的代码编写得好像您期望得到一个同步的答案,并且您可以使用fs.readFileSync等同步方法使其正常工作。

How to fix it in asynchronous way?如何以异步方式修复它? Write CSV processing in "on(end)" callback or use promises.在“on(end)”回调中编写 CSV 处理或使用承诺。

Promises are much simpler and linear. Promise 更加简单和线性。

First make readCSV to return Promise .首先使readCSV返回Promise

function readCSV(path: string){ //return Promise<any[]> 
  return new Promise((resolve) => {
    var events = [];
    fs.createReadStream(path)
      .pipe(csv())
      .on('data', (row) => {
        // this code called in future
        events.push(row);
    }).on('end', () => {
        // this code called in future to, 
        console.log('CSV file successfully processed. Length: ' + events.length);
        resolve(events); //return csv parsed result
    }); 
  })
}

Then in main app, use Promise.all to wait all fileReading promises.然后在主应用程序中,使用Promise.all等待所有文件fileReading承诺。

function app(){
  // i don't know what is listFiles,
  // i hope it returns sync result
  var file_list = fs.listFiles(folder_path);

  const dataPromises: Promise[] = []
  for (let i = 0; i < file_list.length; i++) {
      const file = file_list[i];
      //launch reading
      dataPromises.push(readCSV(file))
  }
  Promise.all(dataPromises).then(result => {
    //this code will be called in future after all readCSV Promises call resolve(..)
    for(const events of result){
      processCSV(events);    
    }
  })
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM