简体   繁体   中英

How to take two consecutive input with the readline module of node.js?

I am creating a program to take input of two numbers from the command line and then showing there sum in node.js. I am using readline module to take stdin. Below is my code.

const readline = require('readline');

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

const r2 = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

rl.question('Please enter the first number', (answer1) => {
    r2.question('Please enter the second number', (answer2) => {
        var result = (+answer1) + (+answer2);
        console.log(`The sum of above two numbers is ${result}`);
    });
    rl.close();
});

This program just show me "Please enter the first number" and when i enter a number like 5, it takes 5 for second input also and shows the answer 10

It don't ask second question at all. Please check this and tell me what is the problem. And if there is any better way to take multiple input please tell that.

I am a novice user in node.js

No need another variable, just use like this:

const readline = require('readline');

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

rl.question('Please enter the first number : ', (answer1) => {
    rl.question('Please enter the second number : ', (answer2) => {
        var result = (+answer1) + (+answer2);
        console.log(`The sum of above two numbers is ${result}`);
        rl.close();
    });
});

Nested code/callback are terrible to read and maintain, here's a more elegant way to use Promise for asking multiple questions

node 8+

'use strict'

const readline = require('readline')

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

const question1 = () => {
  return new Promise((resolve, reject) => {
    rl.question('q1 What do you think of Node.js? ', (answer) => {
      console.log(`Thank you for your valuable feedback: ${answer}`)
      resolve()
    })
  })
}

const question2 = () => {
  return new Promise((resolve, reject) => {
    rl.question('q2 What do you think of Node.js? ', (answer) => {
      console.log(`Thank you for your valuable feedback: ${answer}`)
      resolve()
    })
  })
}

const main = async () => {
  await question1()
  await question2()
  rl.close()
}

main()
const readline = require("readline")

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

var questions = [
 "Input first number",
 "Input second number",
 "Input third number",
 "Input fourth number",
 "Input fifth number",
];

const askQuestion = (theQuestion) => {
    return new Promise((resolve, reject) => {
        try {
          rl.question(theQuestion + ": ", theAnswer => resolve(theAnswer));
        } catch {
          reject("No Answer");
        }
    })
}

async function start(){
    const answers = [];
    for (question of questions){
        answers.push(await askQuestion(question));
    }
    
    const total = answers.reduce((a, b) => {return Number(a) + Number(b)}); 
    console.log( `The sum of array ${answers} is ${total}`);
    rl.close();
}

start();
 

For those interested I put together this little module that takes an array of questions and returns a promise that resolves to an array of answers:

const readline = require('readline');

const AskQuestion = (rl, question) => {
    return new Promise(resolve => {
        rl.question(question, (answer) => {
            resolve(answer);
        });
    });
}

const Ask = function(questions) {
    return new Promise(async resolve => {
        let rl = readline.createInterface({
            input: process.stdin,
            output: process.stdout
        });

        let results = [];
        for(let i=0;i < questions.length;i++) {
            const result = await AskQuestion(rl, questions[i]);
            results.push(result);
        }
        rl.close();
        resolve(results);
    })
}

module.exports = {
    askQuestions: Ask 
}

Save that in a file called ask.js (or whatever you like) and use like this:

const { askQuestions } = require('./ask');

askQuestions([
   'What is question 1?',
   'What is question 2?',
   'What is question 3?'
])
    .then(answers => {
        // Do whatever you like with the array of answers
    });

Note: Will need a transpiler or recent version of Node as it uses a lot of ES6 features.

you could use recursion :

var fs = require('fs')
var readline = require('readline')


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

 var keys = []
function gen(rank){
  if(rank > 3)
    {
        //do whatever u want
        var sum_avg = 0
        for (i in keys)
             {
                sum_avg+=Number(keys[i])
             }
         console.log(sum_avg/3); 
         return -1;     
    }
    else 
    { 
        var place = rank>1 ? "th" : "st"
        var total = rank+place 
        rl.question("Please enter the "+total+ " number :",function(answer){
            keys.push(answer)
            //this is where the recursion works
             gen(rank+1)
        })
     }
  }

//pass the value from where you want to start
  gen(1)

I would ask the questions in an async function and wrap readline similarly to how Jason did it above. Although with slightly less code :)

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

function question(theQuestion) {
    return new Promise(resolve => rl.question(theQuestion, answ => resolve(answ)))
}

async function askQuestions(){
    var answer = await question("A great question")
    console.log(answer);
}
const readline = require('readline');

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

const q0 = 'What\'s your name? Nicknames are also acceptable :)';
const q1 = 'What\'s an activity you like doing?';
const q2 = 'What do you listen to while doing that?';
const q3 = 'Which meal is your favourite (eg: dinner, brunch, etc.)';
const q4 = 'What\'s your favourite thing to eat for that meal?';
const q5 = 'Which sport is your absolute favourite?';
const q6 = 'What is your superpower? In a few words, tell us what you are amazing at!';

const arr = [q0, q1, q2, q3, q4, q5, q6];
let res = '';
const askQ = i => {
  if (i < arr.length) {
    rl.question(arr[i], (answer) => {
      res += '\n' + answer;
      askQ(i + 1);
    });
  } else {
      console.log(`Thank you for your valuable feedback: ${res}`);
      rl.close();
  }
};
askQ(0);
const readline = require('readline')

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

const question = (question) => {
  return new Promise((resolve, reject) => {
    rl.question(question, (answer) => {
      resolve(answer)
    })
  })
}

const main = async () => {
  const username = await question('Please enter a username: ');
  const password = await question('Please enter a password: ');
  console.log("result: ", {
      "username" : username,
      "password" : password
  });
  rl.close()
}

main()

I have decided to simplify the code which @jc have written for developers that want to get an output out from the question.

For more optimizing code I found a package node-quick-cli

its not support require() to support change file name.js to.mjs

import readline from 'node-quick-cli';
var readlineq = new readline();
(async () => {
    console.log(await readlineq.question('Question 1 : '));
    console.log(await readlineq.question('question 3 : ',{color:"blue"}));
    console.log(await readlineq.question('Question 2 : ',{bgcolor:"bgBlue"}));
    readlineq.close();
})();
import readline from 'readline'

const CLI = readline.createInterface( { input: process.stdin , output: process.stdout } )

multiLineCI()

async function multiLineCI() {

     const credentials = {
         server: await new Promise( rsl => CLI.question( 'enter server: ' , ans => rsl( ans ) ) ),
         port: await new Promise( rsl => CLI.question( 'enter port: ' , ans => rsl( ans ) ) ),
         username: await new Promise( rsl => CLI.question( 'enter username: ' , ans => rsl( ans ) ) ),
         password: await new Promise( rsl => CLI.question( 'enter password: ' , ans => rsl( ans ) ) )
     }
     
     console.log( credentials )
     
     CLI.close()

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM