在TypeScript中问很多问题

时间:2019-02-04 20:13:40

标签: javascript node.js typescript

我正在尝试构建一个简单的命令行TypeScript应用程序,但是我不知道该怎么做。我在StackOverflow中找到了这段代码:

import * as readline from 'readline';

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

rl.question('Is this example useful? [y/n] ', (answer) => {
  switch(answer.toLowerCase()) {
    case 'y':
      console.log('Super!');
      break;
    case 'n':
      console.log('Sorry! :(');
      break;
    default:
      console.log('Invalid answer!');
  }
  rl.close();
});

它工作正常。有什么办法可以循环吗?我实际上想做的是从MySQL数据库获取一些问题,但是我不知道如何问N次问题。 谢谢!

1 个答案:

答案 0 :(得分:1)

将readline放在循环中是不够的,因为该函数调用是异步的。这意味着Node不会等到用户输入内容。而是用户输入将触发事件,并且回调函数“(answer)=> {...}”将被执行。

重要的是要了解Node是异步的并且是事件驱动的。函数的每次同步执行都可能阻止事件循环,并使Node无响应。

一种可能性是在回调中使用递归。另一个选项是async / await,它使代码具有同步执行的结构。第三种可能性是使用事件(这可能是最好的解决方案),该事件可以在节点文档(https://nodejs.org/api/readline.html#readline_example_tiny_cli)的页面底部看到。

使用代码开始时,最简单的方法可能是使用递归函数(函数在末尾自行调用):

const readline = require('readline');

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


function ask() {
  rl.question('Is this example useful? [y/n/q] ', (answer) => {
    switch(answer.toLowerCase()) {
      case 'y':
      console.log('Super!');
      break;
      case 'n':
      console.log('Sorry! :(');
      break;
      case 'q':
      console.log('Bye!');
      rl.close();
      process.exit();
      default:
      console.log('Invalid answer!');
    }

    ask();
  });
}

ask();

请注意,这是使事情变得非常简单的一种方法。也有类似功能的强大软件包。例如https://www.npmjs.com/package/commander

没有递归,但是有promise和async / await的情况相同:

async function ask() {
  return new Promise(resolve => {
    rl.question('Is this example useful? [y/n/q] ', (answer) => {
      switch(answer.toLowerCase()) {
        case 'y':
        console.log('Super!');
        break;
        case 'n':
        console.log('Sorry! :(');
        break;
        case 'q':
        console.log('Bye!');
        rl.close();
        process.exit();
        default:
        console.log('Invalid answer!');
      }

      resolve();
    });
  });
}

async function start() {
  for (let i = 0; i < 5; i++) {
    await ask();
  }

  rl.close();
}

start();

这将问五个问题(i <5),然后退出。当输入为“ q”时,它也会退出。您也可以使用while(true)代替for(...)在无限循环中运行它。