Search code examples
javascriptasync-awaitecmascript-next

How to resolve an outer async function from an inner function


How do i resolve the outer async function askIfUserIsAMinor with a boolean indicating the user's minor status (true/false) after the user has answered a dialog prompt? For example:

async function askIfUserIsAMinor() {
  let dialogButtons = [
    {
      text: "Yes",
      onPress: () => {
        // I want to return 'false' on the outer async function 
      }
    }, 
    {
      text: "No",
      onPress: () => {
        // I want to return 'true' on the outer async function 
      }
    }
  ];
  dialog.prompt("Are you above the age of 18?", dialogButtons);
}

let userIsAMinor = await askIfUserIsAMinor();
if (userIsAMinor) {
  // let user proceed
} else {
  // show something else
}

Yes, there are many other ways to solve this problem without async/await, but my use case is much more complex than this, this is just a simplified scenario. In ES6, this can be solved by having askIfUserIsAMinor return a promise and having the inner onPress functions call resolve on the outer promise.


Solution

  • This code actually works correctly - promisify the dialog.prompt, then you await on the promise in the async function testMinor - the code I posted earlier fell for the same trap other people always fall for, thinking somehow one can make asynch code synchronous ...

    function askIfUserIsAMinor() {
        return new Promise(function(resolve) {
            let dialogButtons = [{
                text: "Yes",
                onPress: () => resolve(true)
            }, {
                text: "No",
                onPress: () => resolve(false)
            }];
            dialog.prompt("Are you above the age of 18?", dialogButtons);
        });
    }
    async function testMinor() {
        let userIsAMinor = await askIfUserIsAMinor();
        if (userIsAMinor) {
          // let user proceed
        } else {
          // show something else
        }
    }
    

    or

    async function askIfUserIsAMinor() {
        let userIsAMinor = await new Promise(function(resolve) {
            let dialogButtons = [{
                text: "Yes",
                onPress: () => resolve(true)
            }, {
                text: "No",
                onPress: () => resolve(false)
            }];
            dialog.prompt("Are you above the age of 18?", dialogButtons);
        });
        if (userIsAMinor) {
          // let user proceed
        } else {
          // show something else
        }
    }
    askIfUserIsAMinor();