请阅读this very short article以了解我想要做的事情.
重点在于,正如作者所说,我“需要向用户询问几个问题,……验证输入数据并在输入错误时重新提问.”此外,我可能需要做更复杂的事情来验证输入,除了检查正则表达式.例如,请检查以确保用户未在先前的提示下输入当前输入.
我有兴趣重构本文中的主要代码片段,以便它是基于承诺的.我想要这样做的显而易见的原因是,如果我需要提示用户超过两三次,请避免回调地狱.你对如何重构这个有什么建议吗?绊倒我的是对ask()的递归调用,以及如果一个promise失败的事实,那就是它完成了.而这段代码需要反复循环,直到它获得有效的输入.所以我甚至不知道从哪里开始.
此外,如果您有任何“gordian knot”型解决方案,我愿意朝着完全不同的方向前进.也许Node有一个内置的库来做这种我不知道的东西?也许是readline?我不知道但是因为我对这个东西太新了而且readline API对我来说真的没什么意义…
基本上,如果你能想出任何重构方法,这样我就不必深入回调噩梦,我将不胜感激:)
无论如何,这里是完整的代码片段:
function ask(question, format, callback) {
var stdin = process.stdin, stdout = process.stdout;
stdin.resume();
stdout.write(question + ": ");
stdin.once('data', function(data) {
data = data.toString().trim();
if (format.test(data)) {
callback(data);
} else {
stdout.write("It should match: "+ format +"\n");
ask(question, format, callback);
}
});
}
解决方法:
首先,宣传stdin读者:
function askOnce(question){
var stdin = process.stdin, stdout = process.stdout;
stdin.resume();
stdout.write(question + ": ");
return new Promise(res => {
stdin.once('data', function(data) {
res(data.toString().trim());
});
});
}
所以不容易问:
async function ask(question, format){
let answer;
do {
answer = await askOnce(question);
} while(!answer.test(format));
return answer;
}
没有async /等待它有点丑陋(使用递归和promise flattening机制):
function ask(question, format){
return askOnce(question).then(answer => {
if(!answer.test(format))
return ask(question, format);
return answer;
});
}