Node.js synchronous tooltip

I am using the invitation 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 displayed, it does not seem to block code execution, but execution continues, and the last two messages are displayed using the console, while I still need to answer the question.

Is there any way to block?

+8
prompt
source share
6 answers

Since IO in Node is not blocked, you will not find an easy way to make something like this synchronous. Instead, you should move the code to a 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); }); 

either 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); } 
+4
source share

In the library with a request to use Linux, unfortunately, there is no way to block the code. However, I could offer my own sync-prompt library. Like the name, this allows you to simultaneously request users for input.

With it, you simply call the function call and return the user 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 try it if you want.

Remember: DO NOT use this in web applications . It should be used only in command line applications.

+10
source share

Vorpal.js is a library that I created that was recently released. It provides synchronized command execution using an interactive prompt, as you ask. The following code will do what you ask:

 var vorpal = require('vorpal')(); vorpal.command('do sync') .action(function (args) { return 'i have done sync'; }); 

With the above, the prompt will return after the second one will be (only after calling the callback).

+2
source share

An old question, I know, but I found the perfect tool for this. readline-sync gives you a synchronous way to collect user input in a node script.

It is easy to use and does not require any dependencies (I could not use synchronization due to problems with gyp).

From github readme:

 var readlineSync = require('readline-sync'); // Wait for user response. var userName = readlineSync.question('May I have your name? '); console.log('Hi ' + userName + '!'); 

I have nothing to do with the project, but it just made my day, so I had to share it.

+1
source share

I came across this thread and all the solutions:

  • Do not actually provide a synchronous invitation
  • Deprecated and do not work with new versions of node.

And for this reason I created syncprompt , Install it using npm i --save syncprompt , and then just add:

 var prompt = require('syncprompt'); 

For example, this allows you to do:

 var name = prompt("Please enter your name? "); 

It also supports password hints:

 var topSecretPassword = prompt("Please enter password: ", true); 
+1
source share

Since Node.js 8, you can do the following using async / wait:

 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(); } 
+1
source share

All Articles