Node.js同步提示

时间:2012-08-20 17:52:53

标签: node.js prompt

我正在使用prompt library作为Node.js,我有这段代码:

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);

如果显示提示,它似乎不会阻止代码执行,但执行仍在继续,控制台显示最后两条消息,而我仍然需要回答问题。

有没有办法让它阻止?

8 个答案:

答案 0 :(得分:10)

不幸的是,有了flatiron的提示库,就无法阻止代码。但是,我可能会建议我自己的sync-prompt库。顾名思义,它允许您同步提示用户输入。

有了它,您只需发出一个函数调用,并返回用户的命令行输入:

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.

如果你愿意的话,试试吧。

请记住:不要在Web应用程序上使用它。它应该仅用于命令行应用程序。

答案 1 :(得分:4)

由于Node中的IO没有阻塞,你不会找到一种简单的方法来制作这样的同步。相反,您应该将代码移动到回调中:

  ...

  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);
  });

或者提取它并调用提取的函数:

  ...

  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 :(得分:3)

从Node.js 8开始,您可以使用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();
}

答案 3 :(得分:2)

Vorpal.js是我刚刚发布的库。它提供了同步命令执行和交互式提示,就像你问的那样。以下代码将按您的要求执行:

var vorpal = require('vorpal')();

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

如上所述,提示将在一秒钟之后返回(仅在调用回调之后)。

答案 4 :(得分:1)

老问题,我知道,但我刚刚找到了完美的工具。 readline-sync为您提供了一种在节点脚本中收集用户输入的同步方法。

它易于使用,并且不需要任何依赖(由于gyp问题,我无法使用sync-prompt)。

来自github自述文件:

var readlineSync = require('readline-sync');

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

我没有以任何方式参与该项目,但它只是成了我的一天,所以我不得不分享。

答案 5 :(得分:1)

我遇到过这个帖子和所有解决方案:

  • 实际上并未提供同步提示解决方案
  • 过时且无法使用新版本的节点。

因此我创建了syncprompt 。使用npm i --save syncprompt安装它,然后添加:

var prompt = require('syncprompt');

例如,这将允许您执行:

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

它还支持提示输入密码:

var topSecretPassword = prompt("Please enter password: ", true);

答案 6 :(得分:0)

这是无依赖、同步的,适用于 Windows、Linux 和 OSX:

// Synchronously prompt for input
function prompt(message)
{
    // Write message
    process.stdout.write(message);

    // Work out shell command to prompt for a string and echo it to stdout
    let cmd;
    let args;
    if (os.platform() == "win32")
    {
        cmd = 'cmd';
        args = [ '/V:ON', '/C', 'set /p response= && echo !response!' ];
    }
    else
    {
        cmd = 'bash';
        args = [ '-c', 'read response; echo "$response"' ];
    }

    // Pipe stdout back to self so we can read the echoed value
    let opts = { 
        stdio: [ 'inherit', 'pipe', 'inherit' ],
        shell: false,
    };

    // Run it
    return child_process.spawnSync(cmd, args, opts).stdout.toString().trim();
}

答案 7 :(得分:0)

const buffer = Buffer.alloc(1024);
require("fs").readSync(process.stdin.fd, buffer);
console.log(buffer.toString());