简体   繁体   English

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

[英]Repeatedly prompt user until resolved using nodeJS async-await

I try repeteadly asking question to user until they gave the correct answer using this code. 我尝试向用户重复询问问题,直到他们使用此代码给出正确的答案。

The problem is, it won't resolve if the user doesn't gave the right answer at the first time. 问题是,如果用户第一次没有给出正确的答案,它将无法解决。

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();
})();

Here are the terminal outputs for each condition: 以下是每种情况的终端输出:

When user gave the right answer the first time it was fine ... 当用户第一次给出正确答案时,它很好......

How old are you? 14
USER AGE: 14

When user gave the wrong answer it was stuck (won't resolve and process won't exit) ... 当用户给出了错误的答案时,它被卡住了(不会解决,处理也不会退出)......

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

When user doesn't gave any answer it was also stuck ... 当用户没有给出任何答案时,它也被卡住了......

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

Could anyone explain what happened or give me any reference to an article/video that explain this nature? 任何人都可以解释发生的事情,或者给我一些解释这种性质的文章/视频吗?

Btw, i try to do this using async/await for learning purpose (trying to learn how to do things asynchronously). 顺便说一下,我尝试使用async / await进行学习(尝试学习如何异步处理)。 I already tried this without async/await (promptAge() doesn't return any promise) and it was okay. 我已经尝试过没有async / await(promptAge()不返回任何承诺)并且没关系。

Thank you for your attention. 感谢您的关注。

It's nothing to do with parseInt() although skellertor is advising good practice. 它与parseInt()无关,尽管skellertor建议良好实践。

The problem is that you're generating a new Promise every time promptAge() is called - but the original caller ie start() only has visibility of the first Promise. 问题是你每次调用promptAge()时都会生成一个新的Promise - 但是原始调用者ie start()只能看到第一个Promise。 If you enter a bad input, promptAge() generates a new Promise (inside a never-resolved Promise) and your success code will never run. 如果输入错误的输入, promptAge()生成一个新的Promise(在未解析的Promise中),您的成功代码将永远不会运行。

To fix this, only generate one Promise. 要解决此问题,只需生成一个Promise。 There are more elegant ways to do this but for clarity, and to avoid hacking the code into something unrecognisable... 有更优雅的方法来做到这一点,但为了清晰,并避免将代码破解成无法识别的东西......

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();
})();

It looks like it has to do with your parseInt() function. 看起来它与你的parseInt()函数有关。 In both cases you are passing a non-Number value. 在这两种情况下,您都传递非Number值。 First check if it is a number before parsing it into an int. 首先检查它是否是一个数字,然后再将其解析为int。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM