Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何阅读user input Node.js-使用承诺重构_Javascript_Node.js_Command Line_Promise - Fatal编程技术网

Javascript 如何阅读user input Node.js-使用承诺重构

Javascript 如何阅读user input Node.js-使用承诺重构,javascript,node.js,command-line,promise,Javascript,Node.js,Command Line,Promise,请阅读以了解我正在尝试做的事情 主要的一点是,正如作者所说,我“需要问用户几个问题,……验证输入数据,并在输入错误时重新提问。”此外,我可能需要做更复杂的事情来验证输入,除了对照正则表达式进行检查。例如,检查以确保当前输入不是由用户在前面的提示中输入的 我感兴趣的是重构本文中的主要代码片段,使其基于承诺。我想这样做的明显原因是为了避免在需要提示用户两到三次以上时出现回调地狱。你对如何进行重构有什么建议吗?让我大吃一惊的是对ask()的递归调用,还有一个事实:如果承诺失败,那就是:它完成了。然而,

请阅读以了解我正在尝试做的事情

主要的一点是,正如作者所说,我“需要问用户几个问题,……验证输入数据,并在输入错误时重新提问。”此外,我可能需要做更复杂的事情来验证输入,除了对照正则表达式进行检查。例如,检查以确保当前输入不是由用户在前面的提示中输入的

我感兴趣的是重构本文中的主要代码片段,使其基于承诺。我想这样做的明显原因是为了避免在需要提示用户两到三次以上时出现回调地狱。你对如何进行重构有什么建议吗?让我大吃一惊的是对
ask()
的递归调用,还有一个事实:如果承诺失败,那就是:它完成了。然而,这段代码需要反复循环,直到得到有效的输入。所以我甚至不知道从哪里开始

此外,如果你有任何“戈尔迪安结”类型的解决方案,我愿意朝着完全不同的方向走。也许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/await
,则有点难看(使用递归和promise平坦机制):


你在重新发明轮子吗?为什么不使用提示模块?这将以基于承诺的方式从命令提示符获取用户输入


我不明白这个问题。作者谈到了如何“当用户按下enter键时,你必须找出用户正在回答的问题。”这对我来说似乎很简单,只要继续问同样的问题,直到答案有效。因此,如果将once更改为
。on('data')
,则不需要递归,流将继续准备读取下一个输入。只需将所有问题放在一个数组中,并跟踪当前问题的索引即可。如果答案是肯定的,下一个问题,否则问同样的问题。如果不再次调用
ask()。看来这是对的。如何使用
异步函数ask()
?像这样<代码>提问('first question',/D/)。然后((数据)=>{//用第一个输入做点什么。})。然后(()=>{提问('second question',/y | n/)。然后((数据)=>{//用第二个输入做点什么。})
@jeff B完全像这样。试试看;)哈哈。是的,这就是那种“戈尔丁结”我提到的解决方案。我一直在搜索类似的东西。想知道为什么我从来没有找到它?????事实上,我不认为prompt是基于promisify的。但是使用promisify util使其promise-y非常容易。
 function ask(question, format){
   return askOnce(question).then(answer =>  {
      if(!answer.test(format))
         return ask(question, format);
      return answer;
  });
}