如何中止 readline 接口问题?
How to abort a readline interface question?
TL;DR
Once you call rl.question(query[, options], callback)
it looks like there is no way to cancel the question as long als it's pending an answer.
Is there a way to cleanly abort a readline interface question?
我运行使用原生Node.jsReadline模块遇到问题:
我想提供一个简单的暂停或中止功能来干预子程序(如果它花费的时间太长或需要在检查时暂停)。我通过在 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 controller,可以直接写入接口
// 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);
TL;DR
Once you callrl.question(query[, options], callback)
it looks like there is no way to cancel the question as long als it's pending an answer.
Is there a way to cleanly abort a readline interface question?
我运行使用原生Node.jsReadline模块遇到问题:
我想提供一个简单的暂停或中止功能来干预子程序(如果它花费的时间太长或需要在检查时暂停)。我通过在 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 controller,可以直接写入接口
// 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);