This question already has answers here:
How to get input from user nodejs [duplicate]
(2 answers)
Closed 2 years ago.
I want to take input in javascript program using cmd, as I am executing the js program using node through cmd, So how can I do it?
Short Answer: Use readline (built-in nodejs module)
Long Answer:
According to this blog
Streams are the Node.js way of dealing with evented I/O - it's a big topic, and you can read more about them here. For now, we're going to use the built-in readline module which is a wrapper around Standard I/O, suitable for taking user input from command line(terminal).
Here's a simple example. Try the following in a new file:
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);
});
Related
TL;DR
Once you call rl.question(query[, options], callback) it looks like there is no way to cancel the question as long als it's pending an answer.
Is there a way to cleanly abort a readline interface question?
I ran into a problem using the native Node.js Readline module:
I wanted to provide a simple pause-or-abort feature to intervene in a subroutine (if it takes too long or needs pausing while inspection). I achieved this by asking a question over stdio that can be answered parallel to the running subroutine. If an answer is given an intervention is started.
That works all fine. But if the subroutine finishes and no answer was given in that time, the question is no longer needed, so I'm looking for a clean way to "abort" the asked question.
Once you call rl.question(query[, options], callback) it looks like there is no way to cancel the question as long als it's pending an answer.
I created this test code to reproduce the problem:
// setting up the CLI
const rl = require('readline').createInterface({
input: process.stdin,
output: process.stdout
});
// ...somewhere later:
// mockup of subroutine starting
console.log('Start task...');
// ask question to intervene
rl.question('(p)ause/(a)bort: ', answer => {
console.log(`You entered ${answer}`);
// ...handle intervene.
});
// mockup of subroutine ending
setTimeout(()=>{
console.log('... task has ended. Question can be canelled.');
// ...cancel the question
}, 5000);
The temporary solution I came up with was to close the interface, clear the line and open a new interface:
let rl = // ...
//...
// mockup of subroutine ending
setTimeout(() => {
// ... cancel the question
rl.close();
process.stdout.clearLine();
process.stdout.cursorTo(0);
rl = require('readline').createInterface({
input: process.stdin,
output: process.stdout
});
console.log('... task has ended (and question was closed in a very dirty way).');
}, 5000);
It works... but this solution violates multiple coding conventions (separation of concerns, modularity...).
The original readline interface was initialized at a very different location of the program and I feel very unpleasant by casually closing and reopening it just like that. (Imagine another part of the code still keeps hold of the old instance, the original options for .createInterface() getting updated, etc.)
Is there a way to cleanly abort a readline interface question?
It sounds like you need an abort controller
// setting up the CLI
const rl = require('readline').createInterface({
input: process.stdin,
output: process.stdout
});
// mockup of subroutine starting
console.log('Start task...');
// ask question to intervene
const aborter = new AbortController();
rl.question('(p)ause/(a)bort: ', { signal: aborter.signal }, answer => {
console.log(`You entered ${answer}`);
// ...handle intervene.
});
// mockup of subroutine ending
setTimeout(() => {
console.log('... task has ended. Question can be caneled.');
aborter.abort();
}, 5000);
If your version of node doesn't support the abort controller, you can write to the interface directly
// setting up the CLI
const rl = require('readline').createInterface({
input: process.stdin,
output: process.stdout
});
// mockup of subroutine starting
console.log('Start task...');
// ask question to intervene
rl.question('(p)ause/(a)bort: ', answer => {
console.log(`You entered ${answer}`);
// ...handle 'e' answer as ended here here
// ...handle intervene.
});
// mockup of subroutine ending
setTimeout(() => {
console.log('... task has ended. Question can be caneled.');
rl.write("e\n");
}, 5000);
I want Nodejs to save the context like this :
It's just like run Nodejs in CMD or Powershell.
First of all, I type var temp = 10000; and maybe after 10 minutes I type var temp1 = temp it can still save the value of temp.
but in webstorm or some other IDE how can I do it?
for example, I have an abc.js and global.value =10 when I run abc.js it will close when the code is executed. I know some API like express. but if too many async functions in the file, it can't work well.
You can use the readline module to wait for user input and prevent the event loop from being done with. The below code prompts fo a user input, repeats what the user types or exit if the user types "quit". I hope the logic is pretty obvious.
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
prompt: 'Hello> '
});
rl.prompt();
rl.on('line', (line) => {
if (line === 'quit')
rl.close()
else {
console.log(line);
rl.prompt();
}
})
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 2 years ago.
I just started learning Javascript and I was wondering how can I use the portfinder.getPort() function in one of my functions to get a random port every time. This is my code right now:
var portfinder = require('portfinder')
portfinder.getPort(function (err, port) {
var p = port;
});
function toAddress (name) {
return name + p;
}
I know this is wrong but how can I use it?
Thanks in advance.
You should check the usage example on the project's Github page:
There is also examples on the NPM Page
From the docs:
var portfinder = require('portfinder');
portfinder.getPort(function (err, port) {
//
// `port` is guaranteed to be a free port
// in this scope.
//
});
In your code the problem seems to be the way your accessing p is not correct, because it's in a closure and not available outside of the scope of that function.
If you move the declaration of p outside the closure you can then access it from the other function but a better way would be to pass it to toAddress.
I have this problem very often with various Node.js scripts that I write. After everything is done, they do not exit. Usually, it's an unclosed socket or readline interface.
When the script gets bigger, this is really hard to find out. Is there a tool of some sort that would tell me what's NodeJS waiting for? I'm asking for a generic solution that would help debug all cases of NodeJS not exiting when it's supposed to.
Samples:
Exhibit I. - Process stdin blocks node even after listener is removed
const readline = require('readline');
readline.emitKeypressEvents(process.stdin);
if (typeof process.stdin.setRawMode == "function")
process.stdin.setRawMode(true);
const keypressListener = (stream, key) => {
console.log(key);
process.stdin.removeListener("keypress", keypressListener);
}
process.stdout.write("Press any key...");
process.stdin.on("keypress", keypressListener);
Exhibit II. - readline blocks Node if you forget to close the interface
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
Exhibit III. - Forgotten setInterval will also block node, good luck finding it
setInterval(() => { }, 2000);
Would why-is-node-running work? Seems to do exactly what you need.
This question already has answers here:
Node.js spawn with colors?
(2 answers)
Closed 7 years ago.
I have a mocha file full of Selenium tests. When I run mocha from the command line like normal, I get this nice formatted and colorized output thanks to the colors module.
This looks great and works wonderfully, but running manually only runs the tests against a single environment. To run the tests in multiple environments in parallel, Sauce Labs (Selenium cloud hosting) recommends spawning mocha child processes. I built this into a Gulp task in our project.
gulp.task('test', function () {
var targets = [
'windows.chrome',
'windows.firefox',
'windows.ie',
'mac.chrome',
'mac.firefox',
'mac.safari',
'linux.chrome',
'linux.firefox'
];
function run_mocha(target, done) {
var env = Object.assign({}, process.env);
env.TARGET = target;
var mocha = exec('mocha ./test/test-runner.js', {env: env}, done);
['stdout', 'stderr'].forEach((stream) =>
mocha[stream].on('data', (data) => process[stream].write(`${target}:${data}`))
);
}
var jobs = targets.map(
(target) => new Promise(
(resolve, reject) => run_mocha(target, resolve)
)
);
return Promise.all(jobs).then(() => {
console.log('ALL SUCCESSFUL');
});
});
This works great but the output completely loses the colorization. It was also injecting superfluous newlines but I was able to fix that by swapping out console.log and console.error for process.stdout.write and process.stderr.write.
You can see that lines printed from gulp are colorized and work fine, but the minute it spawns the child processes any lines printed from there lose their color. It's not the end of the world but now I'm curious what is going on and how to fix it. I've learned a bit about ANSI escape codes but I'm still very confused about what's going on. Any suggestions?
So I found this question:
Node.js spawn with colors?
It looks like it's an issue with Mocha, where it's detecting that its output is not going to be stdout. You'll need to specifically enable colors:
exec('mocha ./test/test-runner.js --colors')