How to get synchronous readline, or "simulate" it using async, in nodejs?

Colin D picture Colin D · Apr 26, 2017 · Viewed 25.9k times · Source

I am wondering if there is a simple way to get "synchronous" readline or at least get the appearance of synchronous I/O in node.js

I use something like this but it is quite awkward

var readline = require('readline');
var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});

var i = 0;
var s1 = '';
var s2 = '';

rl.on('line', function(line){
    if(i==0) { s1 = line; }
    else if(i==1) { s2 = line; }
    i++;
})

rl.on('close', function() {
    //do something with lines
})'

Instead of this I would prefer if it were as easy as something like

var s1 = getline(); // or "await getline()?"
var s2 = getline(); // or "await getline()?"

Helpful conditions:

(a) Prefer not using external modules or /dev/stdio filehandle, I am submitting code to a code submission website and these do not work there

(b) Can use async/await or generators

(c) Should be line based

(d) Should not require reading entire stdin into memory before processing

Answer

Aishwat Singh picture Aishwat Singh · Jan 19, 2019

Just in case someone stumbles upon here in future

Node11.7 added support for this doc_link using async await

const readline = require('readline');
//const fileStream = fs.createReadStream('input.txt');

const rl = readline.createInterface({
  input: process.stdin, //or fileStream 
  output: process.stdout
});

for await (const line of rl) {
  console.log(line)
}

remember to wrap it in async function otherwise you will get reserver_keyword_error

const start = async () =>{
    for await (const line of rl) {
        console.log(line)
    }
}
start()

To read an individual line you can use the async iterator manually

const it = rl[Symbol.asyncIterator]();
const line1 = await it.next();