繁体   English   中英

Node.js同步提示

[英]Node.js synchronous prompt

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

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

有没有办法让它阻塞?

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

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

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

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

老问题,我知道,但我刚刚找到了完美的工具。 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 + '!');

我不以任何方式参与该项目,但它让我开心,所以我不得不分享。

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

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

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

var prompt = require('syncprompt');

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

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

它还支持提示输入密码:

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

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

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

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

有了上面的,一秒钟后提示会回来(只有在调用回调之后)。

这是无依赖、同步的,适用于 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();
}
const buffer = Buffer.alloc(1024);
require("fs").readSync(process.stdin.fd, buffer);
console.log(buffer.toString());

您可以使用提示同步

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.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM