Javascript 异步等待循环在第370次迭代后停止

Javascript 异步等待循环在第370次迭代后停止,javascript,node.js,loops,async-await,Javascript,Node.js,Loops,Async Await,我正在尝试以块的形式加载一个大的csv文件(大小以GB为单位)。代码如下: lineReader.open(filename,async function(err, reader) { if (err) throw err; var dataArr=[]; while (reader.hasNextLine()) { reader.nextLine(function(err, line) { if(err) throw err; console.lo

我正在尝试以块的形式加载一个大的csv文件(大小以GB为单位)。代码如下:

lineReader.open(filename,async function(err, reader) {
  if (err) throw err;
  var dataArr=[]; 
  while (reader.hasNextLine()) {
    reader.nextLine(function(err, line) {
      if(err) throw err;
      console.log(line);
      dataArr.push(csv_parse(line,headers));
    });
    console.log(dataArr.length);
    if(dataArr.length == 3000){
      console.log(JSON.stringify(dataArr));
      await timeout(6000);
      console.log("timeout");
      dataArr = [];
    }
  }
    reader.close(function(err) {
      if (err) throw err;
    });
});
reader.nextline()在第370行之后停止工作,即使while循环正在执行。然而,当我将wait移到外部时,如果代码似乎工作正常。发生这种情况的原因。

您将承诺(
async/await
)与回调(
reader.nextLine()
)混为一谈,这导致了您的问题

具体来说,您调用
reader.close()
太早了,因为它在读取所有行之前被调用;执行读取的370行可能适合在文件关闭之前从文件中读取的缓冲区

一个解决方案是也让阅读下一行承诺为基础,例如:

const getNextLine = async reader => {
  return new Promise((resolve, reject) => {
    reader.nextLine(function(err, line) {
      if (err) return reject(err);
      resolve(line);
    });
  });
}

lineReader.open(filename, async function(err, reader) {
  if (err) throw err;
  var dataArr = [];
  while (reader.hasNextLine()) {
    let line = await getNextLine(reader);
    dataArr.push(csv_parse(line, headers));
    console.log(dataArr.length);
    if (dataArr.length == 3000) {
      console.log(JSON.stringify(dataArr));
      await timeout(6000);
      console.log("timeout");
      dataArr = [];
    }
  }
  reader.close(function(err) {
    if (err) throw err;
  });
});
您将承诺(
async/await
)与回调(
reader.nextLine()
)混合在一起,这导致了您的问题

具体来说,您调用
reader.close()
太早了,因为它在读取所有行之前被调用;执行读取的370行可能适合在文件关闭之前从文件中读取的缓冲区

一个解决方案是也让阅读下一行承诺为基础,例如:

const getNextLine = async reader => {
  return new Promise((resolve, reject) => {
    reader.nextLine(function(err, line) {
      if (err) return reject(err);
      resolve(line);
    });
  });
}

lineReader.open(filename, async function(err, reader) {
  if (err) throw err;
  var dataArr = [];
  while (reader.hasNextLine()) {
    let line = await getNextLine(reader);
    dataArr.push(csv_parse(line, headers));
    console.log(dataArr.length);
    if (dataArr.length == 3000) {
      console.log(JSON.stringify(dataArr));
      await timeout(6000);
      console.log("timeout");
      dataArr = [];
    }
  }
  reader.close(function(err) {
    if (err) throw err;
  });
});

您的函数在所有情况下都不会返回承诺。您的函数在所有情况下都不会返回承诺。谢谢,这非常有效。但是我仍然不明白为什么在wait timeout()被移出if块时运行代码。此外,即使在370次左右的尝试后不再调用reader.nextLine(),while循环仍在运行(通过在while开始时记录来检查)。while尚未完成时,循环下面的代码是如何执行的。我是否遗漏了一些东西,比如reader.nextline()的回调可能是非阻塞的?@ashthr是的,这是另一件事:
reader.nextline()
根本没有阻塞。当您将
wait
移动到
if
外部时,它将“阻塞”(不完全是异步的),直到达到超时为止,对于读取的每一行(也不完全是,但足够近)。因此,关闭阅读器将更接近于所有行都已实际阅读的点。谢谢,这非常有效。但是我仍然不明白为什么在wait timeout()被移出if块时运行代码。此外,即使在370次左右的尝试后不再调用reader.nextLine(),while循环仍在运行(通过在while开始时记录来检查)。while尚未完成时,循环下面的代码是如何执行的。我是否遗漏了一些东西,比如reader.nextline()的回调可能是非阻塞的?@ashthr是的,这是另一件事:
reader.nextline()
根本没有阻塞。当您将
wait
移动到
if
外部时,它将“阻塞”(不完全是异步的),直到达到超时为止,对于读取的每一行(也不完全是,但足够近)。因此,关闭读卡器将更接近所有行实际已被读取的点。