admin管理员组文章数量:1134597
I have just started using Node.js, and I don't know how to get user input. I am looking for the JavaScript counterpart of the python function input()
or the C function gets
. Thanks.
I have just started using Node.js, and I don't know how to get user input. I am looking for the JavaScript counterpart of the python function input()
or the C function gets
. Thanks.
- nodejs.org/en/knowledge/command-line/…? stackoverflow.com/q/51370592/3001761? – jonrsharpe Commented Apr 23, 2020 at 18:56
- See the official docs-nodejs.org/en/knowledge/command-line/… – Shubham Dixit Commented Apr 23, 2020 at 19:03
- UPDATE: Official Docs Page has been moved to: nodejs.org/en/learn/command-line/… – m-naeem66622 Commented Mar 5, 2024 at 8:24
9 Answers
Reset to default 105There are 4 options you could use. I will walk you through these examples:
(Option 1) readline (async/await):
In my opinion, it is the best option as we can get the user input asynchronously using async
/await
in Node.js. You need to wrap the rl.question
method in a promise to make it work with async
/await
..
const readline = require('readline');
// Create an interface for input and output
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
const askQuestion = (question) => {
return new Promise((resolve) => {
rl.question(question, (answer) => {
resolve(answer);
});
});
};
// Main async function
const main = async () => {
// Get user input using await
const name = await askQuestion('What is your name? ');
// Print the result
console.log(`Hello, ${name}!`);
// Close the readline interface
rl.close();
};
// Call the main async function
main();
(Option 2) prompt-sync: It is a module available on npm and you can refer to the docs for more examples prompt-sync.
npm install prompt-sync
const prompt = require("prompt-sync")({ sigint: true });
const age = prompt("How old are you? ");
console.log(`You are ${age} years old.`);
(Option 3) prompt: It is another module available on npm:
npm install prompt
const prompt = require('prompt');
prompt.start();
prompt.get(['username', 'email'], function (err, result) {
if (err) { return onErr(err); }
console.log('Command-line input received:');
console.log(' Username: ' + result.username);
console.log(' Email: ' + result.email);
});
function onErr(err) {
console.log(err);
return 1;
}
(Option 4) readline (callbacks): Another example with readline
but using callbacks:
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question("What is your name ? ", function(name) {
rl.question("Where do you live ? ", function(country) {
console.log(`${name}, is a citizen of ${country}`);
rl.close();
});
});
rl.on("close", function() {
console.log("\nBYE BYE !!!");
process.exit(0);
});
This can also be done natively with promises. It is also more secure then using outside world npm modules. No longer need to use callback syntax.
Updated answer from @Willian. This will work with async/await syntax and ES6/ES7.
const readline = require('readline');
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
const prompt = (query) => new Promise((resolve) => rl.question(query, resolve));
// Usage inside aync function do not need closure demo only
(async() => {
try {
const name = await prompt("What's your name: ");
// Can use name for next question if needed
const lastName = await prompt(`Hello ${name}, what's your last name?: `);
// Can prompt multiple times
console.log(name, lastName);
rl.close();
} catch (e) {
console.error("Unable to prompt", e);
}
})();
// When done reading prompt, exit program
rl.on('close', () => process.exit(0));
If you want to use ESM (import
instead of require
):
import * as readline from 'node:readline/promises'; // This uses the promise-based APIs
import { stdin as input, stdout as output } from 'node:process';
const rl = readline.createInterface({ input, output });
const answer = await rl.question('What do you think of Node.js? ');
console.log(`Thank you for your valuable feedback: ${answer}`);
rl.close();
Source: https://nodejs.org/api/readline.html#readline
Note that this is a a new feature. From the source linked above, it seems like node v17.9.1 or above is required.
The other solutions here are either async, or use the blocking prompt-sync
. I want a blocking solution, but prompt-sync
consistently corrupts my terminal.
I found a lovely answer here which offers a good solution.
Edit: see an improved version for Linux here.
Create the function:
const prompt = msg => {
fs.writeSync(1, String(msg));
let s = '', buf = Buffer.alloc(1);
while(buf[0] - 10 && buf[0] - 13)
s += buf, fs.readSync(0, buf, 0, 1, 0);
return s.slice(1);
};
Use it:
const result = prompt('Input something: ');
console.log('Your input was: ' + result);
Disclaimer: I'm cross-posting my own answer from here.
This also works well:
const fs = require('fs');
process.stdin.resume();
process.stdin.setEncoding('utf-8');
let inputString = '';
let currentLine = 0;
process.stdin.on('data', inputStdin => {
inputString += inputStdin;
});
process.stdin.on('end', _ => {
inputString = inputString.replace(/\s*$/, '')
.split('\n')
.map(str => str.replace(/\s*$/, ''));
main();
});
function readLine() {
return inputString[currentLine++];
}
function main() {
const ws = fs.createWriteStream(process.env.OUTPUT_PATH);
const n = parseInt(readLine(), 10); // Read and integer like this
// Read an array like this
const c = readLine().split(' ').map(cTemp => parseInt(cTemp, 10));
let result; // result of some calculation as an example
ws.write(result + "\n");
ws.end();
}
Here my process.env.OUTPUT_PATH is set, if yours is not, you can use something else.
The answer from aggregate1166877 didn't work on linux, causing ESPIPE and ESAGAIN errors without two changes.
This solution fixes those:
let stdin = fs.openSync("/dev/stdin","rs");
const read = function(message) {
fs.writeSync(process.stdout.fd, message + " ");
let s = '';
let buf = Buffer.alloc(1);
fs.readSync(stdin,buf,0,1,null);
while((buf[0] != 10) && (buf[0] != 13)) {
s += buf;
fs.readSync(stdin,buf,0,1,null);
}
return s;
}
It is a form of asynchronous input/output handling in Node.js. We used standard input and output streams to interact with the user or process input and output data. I have used it in hackerank question.
process.stdin.resume();
process.stdin.setEncoding("utf-8");
var stdin_input = "";
process.stdin.on("data", function (input) {
stdin_input += input; // Reading input from STDIN using `data` event.
});
//the `end `event is used to know when input reading is complete.
process.stdin.on("end", function () {
main(stdin_input); //passing a parameter in main function
});
function main(inp){
process.stdout.write(inp);
}
Basically, a function like input()
that exists in Python is not available in NodeJs, on the other hand, there is no clear and simple method to get data from the input.
But in general, this goal can be achieved in two ways:
- Using internal modules available in NodeJs.
This method requires a lot of configuration, so for someone new to NodeJs, it may be too complicated and you may not get the result you want.
- In the second method, it is better to use external modules (packages).
In this way, the complications of this work are minimized and you can reach this goal very easily.
For the second way, there are many packages, one of them is Softio, which has the same methods you mentioned.
To use Softio, just follow the instructions below step by step:
- First you need to install this package. Just run the following command in your project path:
npm install softio
There is no need to worry, when you have installed Node Js, you have also installed npm and you can run the above command.
- Then it is enough to write the following code to get the data from user:
const softio = require( 'softio' );
async function main() {
const name = await softio.input( 'Enter your name: ' );
const age = await softio.readNumber( 'Enter your age: ' );
if ( age < 18 ) {
softio.write( `Sorry, your age is under 18 :(` );
return;
}
softio.writeln( 'welcome.' );
}
main();
The important thing is that reading data from stdin (the same as getting data from the user) in NodeJs is executed concurrently, so to manage this concurrency you must use the keyword 'await', on the other hand, to use this keyword you must You must be inside a function that is 'async'. This point is related to concurrency management in JavaScript.
import { createInterface } from "node:readline/promises";
async function input(prompt: string): Promise<string> {
const rl = createInterface(process.stdin, process.stdout)
const answ = await rl.question(prompt)
rl.close()
return answ
}
const name = await input("what's your name: ")
console.log("your name is", name)
本文标签: javascriptGet user input through Nodejs consoleStack Overflow
版权声明:本文标题:javascript - Get user input through Node.js console - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736838962a1955012.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论