-2

I have the following function that works fine, except I need to wait until it finishes to execute the next statement:

zohoAuth.zoho_oAuth = function () {
    // return new Promise((resolve, reject) => {

        zohoAuth.state = utils.uuid();

        const url = zohoAuth.authorizationURL();

        zohoAuth.popUp(url);
        getAuthCodeFromCatalyst();
        //setTimeout(getAuthCodeFromCatalyst,1000);
        function getAuthCodeFromCatalyst() {
            return new Promise(function (resolve, reject) {
                (async function waitForFoo() {
                    const gotAuthState = await zohoAuth.getUserDataFromStorageState(zohoAuth.state)
                    await gotAuthState;
                    if (gotAuthState) return resolve();
                    setTimeout(waitForFoo, 1000);
                })();
            });
        }


        console.log("bottom of zoho auth")
        return true;
    // });
}

I call the function with this:

zohoAuth.zoho_oAuth();
console.log("done waiting");

How do i wait for this to finish?

Jamiec
  • 133,658
  • 13
  • 134
  • 193
  • 3
    Await it? Use .then? Also why do you have a regular function that returns a new Promise that wraps an async IIFE, rather than just writing an async function? – jonrsharpe Oct 06 '21 at 16:35
  • Also, awaiting `getUserDataFromStorageState` and then awaiting the result looks odd. Are you sure you're using this tool correctly? – Jamiec Oct 06 '21 at 16:37
  • The above function works for what I want it do do. I am waiting for the user to press OK, then reading the result from a database. So I am calling 'getUserDataFromStorageState' every second. Which the function does. I just need to wait until I get the answer from the database – Bob_Lozinak Oct 06 '21 at 17:01

3 Answers3

2

You're making this harder on yourself. Make sure to avoid the explicit promise constructor anti-pattern -

zohoAuth.zoho_oAuth = function () {
  zohoAuth.state = utils.uuid();
  const url = zohoAuth.authorizationURL();
  zohoAuth.popUp(url);
  return zohoAuth.getUserDataFromStorageState(zohoAuth.state);
}

You can access the result by attaching a .then handler to the result of your function call -

zohoAuth.zoho_oAuth()
  .then(authState => console.log("bottom of auth state", authState))
  .catch(console.error)

If you want to use async and await, go ahead. If an error occurs, don't catch it. Instead allow it to bubble up and be handled by the caller -

async function doAuth (...) {
  const authState = await zohoAuth.zoho_oAuth()
  console.log("received auth state", authState)
  return "done" // or whatever
})

doAuth().then(console.log, console.error)
Mulan
  • 129,518
  • 31
  • 228
  • 259
0

You should consider awaiting on the promise. Below snippet shows the difference of using await -

const asyncFunction = function() {
  return new Promise(function(resolve, reject) {
    setTimeout(() => {
      console.log('inside promise');
      resolve();
    }, 100);
  });
}

function callWithoutAwait() {
  asyncFunction();
  console.log('after without await function');
}

callWithoutAwait();

async function callWithAwait() {
  await asyncFunction();
  console.log('after with await function');
}

callWithAwait();
Nikhil Patil
  • 2,480
  • 1
  • 7
  • 20
0

I was able to accomplish what I needed below is the code. Thanks for the help!

zohoAuth.zoho_oAuth = function() {
    zohoAuth.state = utils.uuid();
    const url = zohoAuth.authorizationURL();
    zohoAuth.popUp(url);
    
    return new Promise(function (resolve, reject) {
        (async function waitForFoo() {
            const gotAuthState = await zohoAuth.getUserDataFromStorageState(zohoAuth.state)
            await gotAuthState;
            if (gotAuthState) return resolve();
            setTimeout(waitForFoo, 1000);
        })();
    });
}

And this is the call:

zohoAuth.zoho_oAuth()
  .then(authState => console.log("bottom of auth state", authState))
  .catch(console.error)
Tyler2P
  • 2,324
  • 26
  • 22
  • 31