反复提示用户,直到使用nodeJS async-await解析

时间:2017-08-18 18:37:24

标签: javascript node.js asynchronous async-await

我尝试向用户重复询问问题,直到他们使用此代码给出正确的答案。

问题是,如果用户第一次没有给出正确的答案,它将无法解决。

var readline = require('readline');
var rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

function promptAge() {
    return new Promise(function(resolve){
        rl.question('How old are you? ', function(answer) {
            age = parseInt(answer);
            if (age > 0) {
                resolve(age);
            } else {
                promptAge();
            }
        });
    });
}

(async function start() {
    var userAge =  await promptAge();
    console.log('USER AGE: ' + userAge);
    process.exit();
})();

以下是每种情况的终端输出:

当用户第一次给出正确的答案时......

How old are you? 14
USER AGE: 14

当用户给出错误的答案时,它会被卡住(不会解决,处理也不会退出)......

How old are you? asd
How old are you? 12
_

当用户没有给出任何答案时,它也被卡住了......

How old are you? 
How old are you? 
How old are you? 12
_

任何人都可以解释发生了什么或者给我一篇解释这种性质的文章/视频吗?

顺便说一下,我尝试使用async / await进行学习(尝试学习如何异步处理)。我已经尝试过没有async / await(promptAge()不返回任何承诺)并且没关系。

感谢您的关注。

2 个答案:

答案 0 :(得分:3)

这与parseInt()无关,尽管skellertor建议良好实践。

问题在于,每次调用promptAge()时都会生成一个新的Promise - 但原始调用者,即start()只能看到第一个Promise。如果您输入了错误的输入,promptAge()会生成一个新的Promise(在未解析的Promise中),您的成功代码将永远不会运行。

要解决此问题,只需生成一个Promise。有更优雅的方法来做到这一点,但为了清晰,并避免将代码破解成无法识别的东西...

var readline = require('readline');
var rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

// the only changes are in promptAge()
// an internal function executes the asking, without generating a new Promise
function promptAge() {
  return new Promise(function(resolve, reject) {
    var ask = function() {
      rl.question('How old are you? ', function(answer) {
        age = parseInt(answer);
        if (age > 0) {
          // internal ask() function still has access to resolve() from parent scope
          resolve(age, reject);
        } else {
          // calling ask again won't create a new Promise - only one is ever created and only resolves on success
          ask();
        }
      });
    };
    ask();
  });
}

(async function start() {
    var userAge =  await promptAge();
    console.log('USER AGE: ' + userAge);
    process.exit();
})();

答案 1 :(得分:1)

看起来它与您的parseInt()功能有关。在这两种情况下,您都传递非Number值。首先检查它是否是一个数字,然后再将其解析为int。