Использование readline в Node.js - PullRequest
       27

Использование readline в Node.js

0 голосов
/ 11 октября 2018

Я пытаюсь использовать readline внутри оператора else if:

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

rl.question("Would you like to see which cars are available? Please type yes/no: ", function(answer) {

if (answer === 'yes'){
// if yes do something
}

}else if(answer === 'no'){
  rl.question("Would you like to search by latitude or longitude instead? If yes, please type latitude and longitude: ");
}else{
  console.log("No worries, have a nice day");
}
rl.close();
});

Как правильно задать пользователю другой вопрос, если пользователь введет «Нет»?

В настоящее время, если пользователь вводит Нет, второй вопрос не задается.

Ответы [ 4 ]

0 голосов
/ 12 октября 2018

Если бы я сделал это, я бы начал с создания обещающей версии функции вопроса readLine:

const question = (str) => new Promise(resolve => rl.question(str, resolve));

И я бы структурировал ее как набор шагов:

const steps = {
  start: async () => {
    return steps.seeCars();
  },
  seeCars: async () => {
    const seeCars = await question("Would you like to see which cars are available? Please type yes/no: ");
    if (seeCars === 'yes') { return steps.showCars(); }
    if (seeCars === 'no') { return steps.locationSearch(); }
    console.log('No worries, have a nice day');
    return steps.end();
  },
  showCars: async () => {
    console.log('showing cars');
    return steps.end();
  },
  locationSearch: async () => {
    const longlat = await question("Would you like to search by latitude or longitude instead? If yes, please type latitude and longitude: ");
    return steps.end();
  },
  end: async () => {
    rl.close();
  },
};

Если вы новичок в асинхронных функциях, обратите внимание, что вам нужно набрать await перед вашим вопросом, чтобы дать команду узлу не продолжать работу, пока вопрос не разрешится с ответом.

Также обратите внимание, что всякий раз, когда мы меняем шагивам нужно return, чтобы остальная часть шага не запускалась.

Вот полная программа, которую вы можете скопировать и поиграть:

const readline = require('readline');

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

// Create a promise based version of rl.question so we can use it in async functions
const question = (str) => new Promise(resolve => rl.question(str, resolve));

// A list of all the steps involved in our program
const steps = {
  start: async () => {
    return steps.seeCars();
  },
  seeCars: async () => {
    const seeCars = await question("Would you like to see which cars are available? Please type yes/no: ");
    if (seeCars === 'yes') { return steps.showCars(); }
    if (seeCars === 'no') { return steps.locationSearch(); }
    console.log('No worries, have a nice day');
    return steps.end();
  },
  showCars: async () => {
    console.log('showing cars');
    return steps.end();
  },
  locationSearch: async () => {
    const longlat = await question("Would you like to search by latitude or longitude instead? If yes, please type latitude and longitude: ");
    return steps.end();
  },
  end: async () => {
    rl.close();
  },
};

// Start the program by running the first step.
steps.start();
0 голосов
/ 11 октября 2018

Метод rl.prompt () записывает настроенное приглашение экземпляров readline.Interface в новую строку в выходных данных, чтобы предоставить пользователю новое местоположение для ввода.Использование setPrompt, когда пользователь вводит «нет», чтобы задать другой вопрос.

const readline = require('readline');
let lastAnswer = '';
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
    prompt: 'Would you like to see which cars are available? Please type yes/no: '
});
rl.prompt();
rl.on('line', (line) => {
    switch (line.trim()) {
       case 'yes':
           lastAnswer = 'yes';
           console.log('great!');
           rl.setPrompt('Would you like to see which cars are available? Please type yes/no: ');
           break;
       case 'no':
           if (lastAnswer === 'no') {
               lastAnswer = '';
               rl.close();
           }
           lastAnswer = 'no';
           rl.setPrompt('Would you like to search by latitude or longitude instead? If yes, please type latitude and longitude: ');
           break;
       default:
           lastAnswer = '';
           console.log(`Say what? I might have heard '${line.trim()}'`);
           break;
    }
    rl.prompt();
}).on('close', () => {
    console.log('Have a great day!');
    process.exit(0);
});
0 голосов
/ 12 октября 2018

Если вы не состоите в браке с пакетом readline, Inquirer - это очень хорошая библиотека npm, которая поддерживает использование обещаний.EG

var inquirer = require('inquirer');
  inquirer.prompt([
     { type: 'confirm',
       name: 'whichCar',
       message: 'Which car do you want to drive?
     }
  ]).then(function(response) {
      if (response.whichCar === true) {
          // do your thing
      } else { 
         // do your second prompt
      }
   })

Если вы должны использовать readline, то вышеупомянутые пользователи очень хорошо объяснили, как должны работать обратные вызовы.Если нет, то я думаю, что Inquirer - сильный выбор с большой гибкостью и настройкой.

0 голосов
/ 11 октября 2018

Функция question требует функции обратного вызова, в противном случае она ничего не делает.https://github.com/nodejs/node/blob/master/lib/readline.js#L270

Из источника Node.js:

Interface.prototype.question = function(query, cb) {
  if (typeof cb === 'function') {
    if (this._questionCallback) {
      this.prompt();
    } else {
      this._oldPrompt = this._prompt;
      this.setPrompt(query);
      this._questionCallback = cb;
      this.prompt();
    }
  }
};
...