javascript - 如何中止 readline 界面问题?
问题描述
TL; DR
一旦你打电话rl.question(query[, options], callback)
,看起来没有办法取消这个问题,只要它正在等待答案。
有没有办法干净地中止 readline 界面问题?
我在使用本机 Node.js Readline模块时遇到了问题:
我想提供一个简单的暂停或中止功能来干预子程序(如果需要太长时间或在检查时需要暂停)。我通过在 stdio 上提出一个问题来实现这一点,该问题可以与正在运行的子例程并行回答。如果给出答案,则开始干预。
这一切都很好。但是,如果子程序完成并且在那段时间没有给出答案,则不再需要这个问题,所以我正在寻找一种干净的方法来“中止”被问到的问题。
一旦你打电话rl.question(query[, options], callback)
,它似乎没有办法取消这个问题,只要它正在等待答案。
我创建了这个测试代码来重现问题:
// setting up the CLI
const rl = require('readline').createInterface({
input: process.stdin,
output: process.stdout
});
// ...somewhere later:
// mockup of subroutine starting
console.log('Start task...');
// ask question to intervene
rl.question('(p)ause/(a)bort: ', answer => {
console.log(`You entered ${answer}`);
// ...handle intervene.
});
// mockup of subroutine ending
setTimeout(()=>{
console.log('... task has ended. Question can be canelled.');
// ...cancel the question
}, 5000);
我想出的临时解决办法是关闭界面,清除线路并打开一个新界面:
let rl = // ...
//...
// mockup of subroutine ending
setTimeout(() => {
// ... cancel the question
rl.close();
process.stdout.clearLine();
process.stdout.cursorTo(0);
rl = require('readline').createInterface({
input: process.stdin,
output: process.stdout
});
console.log('... task has ended (and question was closed in a very dirty way).');
}, 5000);
它可以工作......但这个解决方案违反了多种编码约定(关注点分离、模块化......)。
原来的readline界面是在程序的一个非常不同的位置初始化的,就这样随便关闭再重新打开感觉很不爽。(想象一下代码的另一部分仍然保留旧实例、.createInterface()
获取更新的原始选项等)
有没有办法干净地中止 readline 界面问题?
解决方案
听起来你需要一个中止控制器
// setting up the CLI
const rl = require('readline').createInterface({
input: process.stdin,
output: process.stdout
});
// mockup of subroutine starting
console.log('Start task...');
// ask question to intervene
const aborter = new AbortController();
rl.question('(p)ause/(a)bort: ', { signal: aborter.signal }, answer => {
console.log(`You entered ${answer}`);
// ...handle intervene.
});
// mockup of subroutine ending
setTimeout(() => {
console.log('... task has ended. Question can be caneled.');
aborter.abort();
}, 5000);
如果你的node版本不支持abort控制器,可以直接写接口
// setting up the CLI
const rl = require('readline').createInterface({
input: process.stdin,
output: process.stdout
});
// mockup of subroutine starting
console.log('Start task...');
// ask question to intervene
rl.question('(p)ause/(a)bort: ', answer => {
console.log(`You entered ${answer}`);
// ...handle 'e' answer as ended here here
// ...handle intervene.
});
// mockup of subroutine ending
setTimeout(() => {
console.log('... task has ended. Question can be caneled.');
rl.write("e\n");
}, 5000);
推荐阅读
- google-chrome - 有没有办法让 chrome devtools 无法检测到?
- javascript - 编剧错误:未下载 Firefox 修订版。运行“npm install”或“yarn install”
- java - 默认文件管理器从应用程序打开文件夹
- python - 比较python中2个数据帧中的行时的if语句
- mysql - SQL Management Studio - 数据库图不显示创建的每个表
- java - 根据 Java EE 中的配置注入服务
- c++ - C++ 析构函数被意外调用双向链表
- sql - 如何按升序对包含数字和字母数字值的 SQL 行进行排序?
- javascript - 如何使用异步等待
- angular - 将文件从 Angular 8 发送到 NodeJS 的问题