NodeJS - rl.on() - read multiple numbers in multiple lines

507 Views Asked by At

EDIT : Thanks for the answers. I got the solution to achieve below with Promises. If this can be done without it in a simpler way please answer :)

I need to take standard input like below

3 60
120 30
100 25
30 10

Variable form for above

n W
v1 w1
v2 w2
v3 w3
. .
. .
. .
vn wn

v and w values will be stored in v[ ] and w[ ] arrays

How can I do it using rl.on()?

My code looks like below. I am not sure on how to pass 'n' in question2 while calling it and the code is not working as expected in general because of asynchronous behaviour which I'm not quite clear about. Any best practices on taking multiple numbers in multiple line inputs in NodeJS would be helpful.

    var readline = require('readline');
    var rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout,
        terminal: false
      });
    
      const question1 = () => {
        return new Promise((resolve, reject) => {
          rl.on('line', (line) => {
            const n = line.split(" ")[0];
            const capactity = line.split(" ")[1];
            console.log(n)
            console.log(capactity)
            resolve()
          })
        })
      }
      
      const question2 = n => {
        return new Promise((resolve, reject) => {
        for(var i=0; i<n; i++){
            rl.on('line', (line) => {        
                values.push(line.split(" ")[0]);
                weights.push(line.split(" ")[1]);
                console.log(values);
                console.log(weights);
                resolve()
            })
        }
          
        })
      }
      
      const main = async () => {
        await question1()
        await question2()
        rl.close()
      }
      
      main()
1

There are 1 best solutions below

3
On

You'll need to return the values needed from question1 and pass them as parameters to question2:

I would also try to get rid of any callback pattern when using async-await, so changing the

new Promise((resolve) => {
  rl.on('line', (line) => {
    // calculate
    resolve();
  })
})

to

const line = await new Promise(resolve => rl.on('line', resolve));
// calculate

See below:

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

const question1 = async () => {
    const line = await new Promise(resolve => rl.on('line', resolve)); 
    const n = line.split(" ")[0];
    const capactity = line.split(" ")[1];
    return { n, capactity };
}

const question2 = async (n) => {
    const values = [];
    const weights = [];
    for(let i = 0; i < n; i++) {
        const line = await new Promise(resolve => rl.on('line', resolve)); 
        values.push(line.split(" ")[0]);
        weights.push(line.split(" ")[1]);
    }

    return { values, weights };
}

const main = async () => {
    const { n, capactity } =  await question1();
    const { weights, values } = await question2(n);
    rl.close();
    console.log(weights, values);
}

main();