Node.js中readline结合setTimeout逐行延迟执行问题咨询
The Root Cause
Let’s break down what’s happening with your current code:
function readFile(){ var lineReader = require('readline').createInterface({ input: require('fs').createReadStream(FILE_PATH) }); lineReader.on('line', function (line) { setTimeout(() => { console.log("HEYYYYY"); }, 10000); }); }
When the line event fires for each line in your file, you’re immediately scheduling a 10-second timeout. Since reading lines from a file happens extremely fast (we’re talking milliseconds for most files), all these timeouts get queued up at almost the exact same moment. So after 10 seconds, every single timeout triggers at once—boom, all your "HEYYYYY" messages print in a batch.
Fixes to Print Line-by-Line with 10-Second Delays
Here are a few reliable ways to get the sequential, delayed output you want:
Option 1: Collect All Lines First, Then Process One-by-One
First, we’ll gather all lines from the file into an array, then iterate through them with a 10-second pause between each print. This is straightforward and easy to debug:
const fs = require('fs'); const readline = require('readline'); async function readFile() { const lines = []; const lineReader = readline.createInterface({ input: fs.createReadStream(FILE_PATH) }); // Use async iteration to collect all lines (Node.js 11+) for await (const line of lineReader) { lines.push(line); } // Loop through lines with delays for (const line of lines) { console.log("HEYYYYY"); // You can replace this with `line` if you want to print the actual line content await new Promise(resolve => setTimeout(resolve, 10000)); } } readFile();
Option 2: Chain Promises as Lines Are Read
If you’re working with a huge file and don’t want to load all lines into memory at once, this approach builds a promise chain. Each line’s delay won’t start until the previous one finishes:
const fs = require('fs'); const readline = require('readline'); function readFile() { let promiseChain = Promise.resolve(); // Start with a resolved promise const lineReader = readline.createInterface({ input: fs.createReadStream(FILE_PATH) }); lineReader.on('line', (line) => { // Append a new step to the chain promiseChain = promiseChain.then(() => { return new Promise(resolve => { console.log("HEYYYYY"); setTimeout(resolve, 10000); }); }); }); // Optional: Run code when all lines are processed lineReader.on('close', () => { promiseChain.then(() => { console.log("All lines have been printed!"); }); }); } readFile();
Option 3: Offset Timeouts by Line Number
A quick-and-dirty (but less flexible) fix is to multiply the delay by the line number. This works because each line’s timeout is offset by 10 seconds based on its position in the file:
const fs = require('fs'); const readline = require('readline'); function readFile() { let lineIndex = 0; const lineReader = readline.createInterface({ input: fs.createReadStream(FILE_PATH) }); lineReader.on('line', (line) => { lineIndex++; setTimeout(() => { console.log("HEYYYYY"); }, 10000 * lineIndex); }); } readFile();
Heads up: This relies on lines being read in order (which readline guarantees for local files), but it’s less adaptable if you ever need to change the delay logic later.
Final Thoughts
All these methods ensure each "HEYYYYY" prints 10 seconds after the last one, instead of all at once. For most cases, Option 1 or 2 are the most robust—pick whichever fits your file size and code style best.
内容的提问来源于stack exchange,提问作者Joel Alvarez Myrrie

