使用Node.js进行用户输入处理

5
我有以下Node.js代码,行为很奇怪:
#!/usr/bin/env node

"use strict";

var readline = require('readline');

var rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

function input(prompt) {
    rl.question(prompt, function (x) {
        rl.close();

        console.log("debug: " + x);
        return x;
    });
}

function main() {
    var n = input("Number: ");
//    console.log("value: " + n);    // problematic line
}

main();

我想模仿Python的raw_input函数,即从用户那里读取一行。在显示提示后,程序应被阻塞,直到用户按下Enter键。

如果“有问题的行”在注释中,它可以工作,程序会等待输入。然而,如果这行不在注释中,那么程序不会等待输入,n就会变成undefined。为什么?如何编写一个返回用户输入的函数?

1个回答

3
那是因为你期望输入的执行等到调用返回,但实际上并非如此。问题出在前一行。首先,输入没有返回任何内容,返回语句是问题回调函数的返回,但你似乎误解了执行流程,我们都曾经遇到过这样的死胡同(在像这样的死胡同中,你很快就会明白)。
  1. 脚本已加载
  2. 声明和定义rl、input和main
  3. 主函数执行
  4. 将n定义为input的结果从这里开始异步有趣
  5. 由于question是异步的,它的执行开始,但不会阻塞进程
  6. input返回undefined(而你仍在等待输入)
  7. 你打印了那个undefined
  8. 你在输入框中输入了一些内容
  9. question()完成其执行并调用回调函数(即你作为第二个参数提供的函数)
  10. rl被关闭
  11. 回调函数返回该行,并被void吞噬了(这不是技术术语,只是一个比喻)

你可能想这样做:

#!/usr/bin/env node

"use strict";

var readline = require('readline');

var rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

function input(prompt, callback) {
    rl.question(prompt, function (x) {
        rl.close();
        callback(x);
    });
}

function main() {
    var n = input("Number: ", console.log);
}

main();

如果你是javascript和node的新手,你可能会发现使用learnyounodenode code school path非常有用,甚至,如果你有时间、金钱和机会,可以阅读Brad Dayley的Node.js, MongoDB, and AngularJS Web Development


谢谢,但之后如何处理 n 呢?例如,如果我在 main() 的末尾添加这行代码:console.log(Number(n)+1);,那么问题又出现了。或者如果我想读取两个数字并在 main 中将 n1n2 相加并打印结果。是的,我是新手,感谢提供有用的链接。 - Jabba
1
之后你想做的任何事情都必须在回调函数中完成。不要传递console.log,而是传递一个带有下一步操作的自定义函数。 - Luis Sieira
如果你传递的是main本身,你会得到一个漂亮的鹦鹉提示,重复你的输入并再次询问。如果你传递一个使用你的输入进行系统调用并在之后调用main的函数,你将得到一个shell,以此类推... - Luis Sieira
如果您将该行添加到主程序中,您正在尝试从未定义的内容创建数字,这是从输入获取的结果(它不返回任何内容)。我认为这会给您NaN,但无论如何... - Luis Sieira
Brad Dayley的链接已经失效。这是该书在亚马逊上的购买链接 - Jabba

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接