10

我正在使用 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);

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

有没有办法让它阻塞?

4

9 回答 9

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 应用程序上使用它。它应该只用于命令行应用程序。

更新:根本不要使用这个库。坦率地说,这完全是个笑话。

于 2014-05-21T16:27:20.210 回答
6

从 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() {
  var promptInput = await readLineAsync("Give me some input >");
  console.log("Won't be executed until promptInput is received", promptInput);
  rl.close();
}
于 2017-10-12T01:37:26.280 回答
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);
}
于 2012-08-20T18:01:06.407 回答
3

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

它使用起来非常简单,并且不需要任何依赖项(由于 gyp 问题,我无法使用同步提示)。

来自 github 自述文件:

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

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

我与这个项目没有任何关系,但它让我很开心,所以我不得不分享。

于 2016-09-16T20:46:04.450 回答
2

我遇到了这个线程和所有解决方案:

  • 实际上不提供同步提示解决方案
  • 已过时,不适用于新版本的节点。

出于这个原因,我创建了syncprompt . 安装它,npm i --save syncprompt然后添加:

var prompt = require('syncprompt');

例如,这将允许您执行以下操作:

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

它还支持提示输入密码:

var topSecretPassword = prompt("Please enter password: ", true);
于 2017-01-11T16:04:01.020 回答
1

Vorpal.js是我创建的一个库,最近刚刚发布。它提供了具有交互式提示的同步命令执行,就像您要求的那样。下面的代码将满足您的要求:

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

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

有了上述,提示将在一秒钟后返回(仅在调用回调后)。

于 2015-10-01T21:18:24.393 回答
1

这是无依赖的,同步的,适用于 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();
}
于 2020-12-29T21:21:07.707 回答
0
const buffer = Buffer.alloc(1024);
require("fs").readSync(process.stdin.fd, buffer);
console.log(buffer.toString());
于 2021-04-02T16:30:33.810 回答
0

您可以使用提示同步

const prompt = require('prompt-sync')()

const ans = prompt('How many more times? ') // get input from the user.

PS prompt-sync 行为很奇怪,如果提示信息包含换行符,所以如果你需要多行提示,只需使用console.log()

const prompt = require('prompt-sync')()

console.log('How many more times?\n')
const ans = prompt('') // get input from the user.
于 2022-02-19T13:55:39.033 回答