node.jsreadline

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


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


Solution

  • Just in case someone stumbles upon here in future

    Node 11.7 added support for this 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 a reserved_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();