逐行节点 JS 提示输入不起作用

问题描述

我已经开始使用 node js 并且正在使用逐行依赖项。我已经正确地逐行安装,它在文件夹中。目前,我的应用程序将运行但不会提示用户输入答案。我的代码如下:

var rlname;
var rlage;
var rlcolor;

// Create reading interface
const readline = require('readline');

const rl = readline.createInterface ({
    input: process.stdin,output: process.stdout,prompt: '>'
});

// Ask a question
function getUserinput()
{
    rl.question("What is your name? \n",(name) => {
        console.log(name);
        rlname = name;
        // Log answer in JSON
    })

    rl.question("What is your age? \n",(age) => {
        console.log(age);
        rlage = age;
        // Log answer in JSON
    })

    rl.question("What is your favorite color? \n",(color) => {
        console.log(color);
        rlcolor = color;
        // Log answer in JSON
    })

    console.log("Hello " + rlname + ",you are " + rlage + " years old and your favorite color is " + rlcolor + ".");
}

getUserinput();
rl.close();

这是产生的结果:

What is your name?
Hello undefined,you are undefined years old and your favorite color is undefined.

解决方法

这里的问题是 readline.question 是异步的,您需要等待每个回调返回,然后才能 (a) 使用输入和 (b) 创建下一个问题。但是,您将在 question 调用之后直接执行 console.log 语句。这可能是将 question 包装到 promise 中的最简单方法,以便您可以等待响应。

以下是使用 Promise 的示例:https://stackoverflow.com/a/47999168/3233827

,

与 Node.js 中的许多模块一样,readline 在回调的基础上工作。您传递给 rl.question 的回调函数不会立即运行;只有在收到用户的输入时才会调用它们。所以你的程序试图一次问三个问题,然后在收到任何答案之前立即记录你的“你好”行。 (您可能没有看到第二或第三个问题,因为 readline 有一些内部缓冲区。)

对于回调,正确的方法是这样嵌套:

var rlname;
var rlage;
var rlcolor;

// Create reading interface
const readline = require('readline');

const rl = readline.createInterface ({
    input: process.stdin,output: process.stdout,prompt: '>'
});

// Ask a question
function getUserInput()
{
    rl.question("What is your name? \n",(name) => {
        console.log(name);
        rlname = name;

        rl.question("What is your age? \n",(age) => {
            console.log(age);
            rlage = age;

            rl.question("What is your favorite color? \n",(color) => {
                console.log(color);
                rlcolor = color;

                console.log("Hello " + rlname + ",you are " + rlage + " years old and your favorite color is " + rlcolor + ".");

                rl.close();
            })
        })
    })
}

getUserInput();

(注意 rl.close 不能被调用,直到所有问题都被问到,所以在最内层的回调中。)

使用带有 Promise 的 async 函数会使这更容易理解,无需嵌套函数和深度缩进。

,

这里的问题是因为这段代码应该是异步的,但写的好像是同步的。

更清楚一点:您要求输入名称,但代码不会等待输入,因为它是异步的。它继续到 console.log 语句并继续使用 rl.close() 关闭输入。

你应该把每个问题放在上一个回调中,最后一个回调中结束语句:

var rlname;
var rlage;
var rlcolor;

// Create reading interface
const readline = require('readline');

const rl = readline.createInterface ({
    input: process.stdin,prompt: '>'
});

// Ask a question
function getUserInput()
{
    // FIRST QUESTION
    rl.question("What is your name? \n",(name) => {
        console.log(name);
        rlname = name;
        
        // SECOND QUESTION
        rl.question("What is your age? \n",(age) => {
            console.log(age);
            rlage = age;
            
            // THIRD QUESTION
            rl.question("What is your favorite color? \n",(color) => {
                console.log(color);
                rlcolor = color;

                // LOG DATA
                console.log("Hello " + rlname + ",you are " + rlage + " years old and your favorite color is " + rlcolor + ".");
                
                // CLOSE CONNECTION
                rl.close();
            })
        })
    })
}

getUserInput();