javascript – 如何读取用户输入Node.js – 使用Promise重构

请阅读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;
  });
}

相关文章

最后的控制台返回空数组.控制台在ids.map函数完成之前运行va...
我正在尝试将rxJava与我已经知道的内容联系起来,特别是来自J...
config.jsconstconfig={base_url_api:"https://douban....
我正在阅读MDN中的javascript,并且遇到了这个谈论承诺并且不...
config.jsconstconfig={base_url_api:"https://douban....
这是我的代码main.cpp:#include<string>#include<...