пользовательский ввод с помощью node.js

У меня есть следующий код 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. Почему? Как написать функцию, которая возвращает пользовательский ввод?


person Jabba    schedule 07.11.2015    source источник


Ответы (1)


Это потому, что вы ожидаете выполнения ввода ожидания до тех пор, пока не будет вызван возврат, а это не так. Проблемная строка действительно предыдущая. Во-первых, ввод ничего не возвращает, оператор return является возвратом функции обратного вызова вопроса, но затем вы, кажется, неправильно понимаете поток выполнения, как и все мы в какой-то момент (вы получите его довольно быстро после некоторого мертвого- заканчивается так)

  1. Ваш скрипт загружен
  2. Вы объявляете и определяете rl, input и main
  3. Основные исполнения
  4. Вы определяете n как результат ввода И вот здесь все становится асинхронно забавным
  5. так как вопрос асинхронный, его выполнение начинается, но не блокирует процесс
  6. input возвращает undefined (пока вы все еще ждете ввода)
  7. вы печатаете это неопределенное
  8. Вы пишете что-то на входе
  9. question() завершает выполнение и вызывает обратный вызов (функция, которую вы указали в качестве второго параметра)
  10. рл закрыт
  11. функция обратного вызова возвращает строку, и она поглощается пустотой (это не техническая терминология, просто метафора)

Вы можете сделать это следующим образом:

#!/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, вам может быть очень полезно использовать learnyounode и путь школы Node Code или даже, если у вас есть время , деньги и возможности, прочитайте Node.js, MongoDB и AngularJS Веб-разработка, Брэд Дейли.

person Luis Sieira    schedule 07.11.2015
comment
Спасибо, а как потом что-то делать с n? Например, если я добавлю эту строку в конец main(): console.log(Number(n)+1);, то это снова проблематично. Или, если я хочу прочитать два числа и добавить n1 и n2 и напечатать результат в main. Да, я новичок в этом и спасибо за полезные ссылки. - person Jabba; 07.11.2015
comment
Все, что вы хотите сделать после этого, должно быть сделано в обратном вызове. Вместо того, чтобы передавать console.log, передайте пользовательскую функцию со следующими операциями. - person Luis Sieira; 07.11.2015
comment
Если вы передадите, например, сам main, вы получите красивую подсказку попугая, повторяющую ваш ввод и запрашивающую снова. Если вы передадите функцию, выполняющую системный вызов с вашим вводом, а затем вызовите main, вы получите оболочку и так далее... - person Luis Sieira; 07.11.2015
comment
Если вы добавите эту строку в основную, вы попытаетесь сделать число из неопределенного, что является результатом, который вы получаете от ввода (он ничего не возвращает), я думал, что это даст вам NaN, но что угодно... - person Luis Sieira; 08.11.2015
comment
Связь с Брэдом Дейли не работает. Вот книга на Amazon. - person Jabba; 08.11.2015