问题
I'm using the prompt library for Node.js and I have this code:
var fs = require('fs'),
prompt = require('prompt'),
toCreate = toCreate.toLowerCase(),
stats = fs.lstatSync('./' + toCreate);
if(stats.isDirectory()){
prompt.start();
var property = {
name: 'yesno',
message: 'Directory esistente vuoi continuare lo stesso? (y/n)',
validator: /y[es]*|n[o]?/,
warning: 'Must respond yes or no',
default: 'no'
};
prompt.get(property, function(err, result) {
if(result === 'no'){
console.log('Annullato!');
process.exit(0);
}
});
}
console.log("creating ", toCreate);
console.log('\nAll done, exiting'.green.inverse);
If the prompt is show it seems that it doesn't block code execution but the execution continues and the last two messages by the console are shown while I still have to answer the question.
Is there a way to make it blocking?
回答1:
Since IO in Node doesn't block, you're not going to find an easy way to make something like this synchronous. Instead, you should move the code into the callback:
...
prompt.get(property, function (err, result) {
if(result === 'no'){
console.log('Annullato!');
process.exit(0);
}
console.log("creating ", toCreate);
console.log('\nAll done, exiting'.green.inverse);
});
or else extract it and call the extracted function:
...
prompt.get(property, function (err, result) {
if(result === 'no'){
console.log('Annullato!');
process.exit(0);
} else {
doCreate();
}
});
...
function doCreate() {
console.log("creating ", toCreate);
console.log('\nAll done, exiting'.green.inverse);
}
回答2:
With flatiron's prompt library, unfortunately, there is no way to have the code blocking. However, I might suggest my own sync-prompt library. Like the name implies, it allows you to synchronously prompt users for input.
With it, you'd simply issue a function call, and get back the user's command line input:
var prompt = require('sync-prompt').prompt;
var name = prompt('What is your name? ');
// User enters "Mike".
console.log('Hello, ' + name + '!');
// -> Hello, Mike!
var hidden = true;
var password = prompt('Password: ', hidden);
// User enters a password, but nothing will be written to the screen.
So give it a try, if you'd like.
Bear in mind: DO NOT use this on web applications. It should only be used on command line applications.
回答3:
Since Node.js 8, you can do the following using async/await:
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
function readLineAsync(message) {
return new Promise((resolve, reject) => {
rl.question(message, (answer) => {
resolve(answer);
});
});
}
// Leverages Node.js' awesome async/await functionality
async function demoSynchronousPrompt(expenses) {
var promptInput = await readLineAsync("Give me some input >");
console.log("Won't be executed until promptInput is received", promptInput);
rl.close();
}
回答4:
Old question, I know, but I just found the perfect tool for this. readline-sync gives you a synchronous way to collect user input in a node script.
It's dead simple to use and it doesn't require any dependencies (I couldn't use sync-prompt because of gyp issues).
From the github readme:
var readlineSync = require('readline-sync');
// Wait for user's response.
var userName = readlineSync.question('May I have your name? ');
console.log('Hi ' + userName + '!');
I'm not affiliated with the project in any way, but it just made my day, so I had to share.
回答5:
I've come across this thread and all the solutions either:
- Don't actually provide a syncronous prompt solution
- Are outdated and don't work with new versions of node.
And for that reason I have created syncprompt
. Install it with npm i --save syncprompt
and then just add:
var prompt = require('syncprompt');
For example, this will allow you to do:
var name = prompt("Please enter your name? ");
It also supports prompting for passwords:
var topSecretPassword = prompt("Please enter password: ", true);
回答6:
Vorpal.js is a library I made that has just recently been released. It provides synchronous command execution with an interactive prompt, like you are asking. The below code will do what you are asking:
var vorpal = require('vorpal')();
vorpal.command('do sync')
.action(function (args) {
return 'i have done sync';
});
With the above, the prompt will come back after a second is up (only after callback is called).
来源:https://stackoverflow.com/questions/12042534/node-js-synchronous-prompt