我正在尝试构建一个简单的命令行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次问题。 谢谢!
答案 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(...)在无限循环中运行它。