dashman
dashman

Reputation: 3028

Using javascript Promise asynchronously

Here's the problem - I call a function and that optionally displays a dialog multiple times and waits for the user to press OK. Then after that - I want to do something else.

I think the solution requires use of Promise. But the async nature of the dialog.alert() call, is throwing me off.

function a()
{
if ( condition_ok )
{
   // there could be multiple dialogs
   //
   for ( int i = 0; i < 2; ++i )
      dialog.alert("press ok").then ( ()=> { console.log("done"); } );
  }
}
a();
// call b() after all the dialogs have been closed in a()
b();

Upvotes: 1

Views: 123

Answers (4)

maazadeeb
maazadeeb

Reputation: 6112

The problem you are facing is that you need to wait for all your asynchronous alerts to be done before calling b. You could store all your asynchronous calls in an array and then use Promise.all() to make sure all of them are done before calling b. Here is how you could do that

// Faking data/objects - START
const condition_ok = true;
const dialog = {
  alert() {
    return new Promise((resolve, reject) => {
      resolve("Done");
    })
  }
}
const b = () => {
  console.log("Call b()")
}
// Faking data/objects - END

function a() {
  let promises = [];
  if (condition_ok) {
    for (let i = 0; i < 2; ++i) {
      promises.push(dialog.alert("press ok").then(() => {
        console.log(`Done with alert() for ${i}`);
      }));
    }
  }
  return promises;
}

Promise.all(a()).then(results => {
  // call b() after all the dialogs have been closed in a()
  b();
});

Upvotes: 0

Jaromanda X
Jaromanda X

Reputation: 1

If you are in an environment that has arrow functions (which your code suggests you do) but doesn't support async/await (which is an excellent answer by @guest271314) you can use the following instead

function a() {
    var p = Promise.resolve();
    if (condition_ok) {
        // there could be multiple dialogs
        //
        for (var i = 0; i < 2; ++i) {
            p = p
            .then(() => dialog.alert('press ok'))
            .then(() => {
                console.log('done');
            });
        }
    }
    return p;
}
a().then(b);

Note: each dialog will wait for the previous to "close", which I think is what your code intended

Upvotes: 3

guest271314
guest271314

Reputation: 1

You can use async/await or Promise.all() and Array.prototype.map()

async function a() {
  if ( condition_ok ) {
    // there could be multiple dialogs
    //
    for ( let i = 0; i < 2; i++ ) {
      let curr = await dialog.alert("press ok");
      console.log("done");
    }
  }
  return
}
// call b() after all the dialogs have been closed in a()
a().then(() => b(), err => console.error(err));

Upvotes: 0

grantonzhuang
grantonzhuang

Reputation: 567

Use Promise.all().

let targets = []
for (let i = 0; i < 2; i++) {
    targets.push(dialog.alert('press ok'))
}
Promise.all(targets).then(([result1, result2]) => {
    b();
})

Upvotes: 0

Related Questions