I copied an async sleep function from here https://stackoverflow.com/a/39914235/7492244 Then I used it basically in this program. https://nodejs.org/api/readline.html#example-read-file-stream-line-by-line
So my own index.js looks like:
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();
I get this mind boggling behaviour that it somehow prints Enter sleep
and Exit sleep
but not DONE
. However it does terminate, and without printing any errors.
I found out after hours of debugging that it works if I remove the call to sleep
. What is wrong with this sleep function?
Edit: Note: I am specifically just trying to understand why the call to sleep
breaks (afaics) the flow of the program. The use case or end goal is not important.
CodePudding user response:
Ok, this one was strange.
It seems like if you don't pause a stream while you do the timeout the process will terminate. No errors either, even try/catch
and try/finally
will fail..
But if you pause & resume, this seems to fix the issue..
eg..
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, if you use sleep in the for await
you don't need to pause.. So it appears if you don't start reading a stream straight away without pausing, that's when the issue occurs.
Of course the other option is just call the sleep before the readline.createInterface
, and the pause
won't be required.
CodePudding user response:
This seem a bit strange that use of reading a stream;
since you can add event like this
const lines = []:
lineReader.on('line', line => lines.push(line))
and delete your for loop, in the end you can have only that
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();
By the way it dosn't work your way since you have a timeout and the strezam close.
Just console.log the lineReader and you will see the status closed at true and multiple data like the timout it handle and everything :P