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 sleep
和 Exit 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/catch
和 try/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
。
我从这里复制了一个异步睡眠函数 然后我基本上在这个程序中使用它。 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 sleep
和 Exit 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/catch
和 try/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
。