JavaScript 异步睡眠功能以某种方式导致程序静默退出

JavaScript async sleep function somehow leads to silent exiting of program

我从这里复制了一个异步睡眠函数 然后我基本上在这个程序中使用它。 https://nodejs.org/api/readline.html#example-read-file-stream-line-by-line

所以我自己的 index.js 看起来像:

const fs = require('fs');
const readline = require("readline");

function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

async function main() {
    const fileStream = fs.createReadStream('input.txt');
    let lineReader = readline.createInterface({
        input: fileStream,
        crlfDelay: Infinity,
    });
    console.log("Enter sleep");
    await sleep(1000);
    console.log("Exit sleep");

    for await (const line of lineReader) {
        console.log("line: " + line);
    }
    console.log("DONE");
}

main();

我得到了这种令人难以置信的行为,它以某种方式打印了 Enter sleepExit sleep 而不是 DONE。但是它确实终止了,并且没有打印任何错误。 经过几个小时的调试,我发现如果我删除对 sleep 的调用,它就可以工作。这个休眠功能有什么问题?

编辑:注意:我特别想了解为什么对 sleep 的调用会中断(afaics)程序的流程。用例或最终目标并不重要。

使用读取流似乎有点奇怪;

因为你可以像这样添加事件

const lines = []:
lineReader.on('line', line => lines.push(line))

并删除你的for循环,最后你只能拥有那个

const fs = require('fs');                                                                                                                                                                                  
const readline = require("readline");                                                                                                                                                                      
                                                                                                                                                                                                           
function sleep(ms) {                                                                                                                                                                                       
  return new Promise((resolve) => setTimeout(resolve, ms));                                                                                                                                                
}                                                                                                                                                                                                          
                                                                                                                                                                                                           
async function main() {                                                                                                                                                                                    
    const lines = [];                                                                                                                                                                                      
    const fileStream = fs.createReadStream('text.txt');                                                                                                                                                    
    let lineReader = readline.createInterface({                                                                                                                                                            
        input: fileStream,                                                                                                                                                                                 
        crlfDelay: Infinity,                                                                                                                                                                               
    });                                                                                                                                                                                                    
    lineReader.on('line', line => lines.push(line))                                                                                                                                                        
    console.log("Enter sleep");                                                                                                                                                                            
    await sleep(1000);                                                                                                                                                                                     
    console.log("Exit sleep");                                                                                                                                                                             
    console.log(lines);                                                                                                                                                                                    
    console.log("DONE");                                                                                                                                                                                   
}                                                                                                                                                                                                          
                                                                                                                                                                                                           
main();

顺便说一下,由于您有超时和 strezam 关闭,因此它无法按照您的方式工作。

只需 console.log lineReader,您将看到状态 closed at true 和多个数据,例如它处理的超时和所有内容:P

好吧,这个很奇怪。

似乎如果您在超时时不暂停流,则该过程将终止。也没有错误,即使 try/catchtry/finally 也会失败..

但是如果您暂停并恢复,这似乎可以解决问题..

例如..

const fs = require('fs');
const readline = require("readline");

function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

async function main() {
    const fileStream = fs.createReadStream('input.txt');
    let lineReader = readline.createInterface({
        input: fileStream,
        crlfDelay: Infinity,
    });
    console.log("Enter sleep");
    lineReader.pause();
    await sleep(1000);
    lineReader.resume();
    console.log("Exit sleep");

    for await (const line of lineReader) {
        console.log("line: " + line);
    }
    console.log("DONE");
}

main();

ps,如果你在 for await 中使用 sleep,你不需要暂停.. 所以如果你不立即开始阅读流而不暂停,那会出现出现问题。

当然,另一种选择是在 readline.createInterface 之前调用睡眠,而不需要 pause