0

I have multiple asynchronous functions that I want to execute one after the other however the next function is executing before the previous one has finished.

async function x() {
  for (...) {
    console.log("awaiting" + i)
    function fooPromise() {
      return new Promise(function(resolve) {
        foo();
        resolve();
      });
    }
    await fooPromise();
    console.log("awaited" + i)
  }
}
async foo(){
  for(...){
     await sleep(1500);    
  }    
  console.log("finished");
}
function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

The expected output should be:

awaiting1
finished
awaited1
awaiting2
finished
awaited2
awaiting3
finished
awaited3

but instead I'm getting:

awaiting1
awaited1
awaiting2
awaited2
awaiting3
awaited3
finished
finished
finished

I'm fairly new to using promises and async so any help would be appreciated.

TDUK
  • 17
  • 1
  • 5

1 Answers1

1
return new Promise(function(resolve) {
   foo();
   resolve();
});

The code you pass to the promise constructor runs immediately and synchronously. The constructor is typically meant for taking code written using callbacks, and then wrapping the callback in a promise (as in your sleep example).

So this code will immediately call foo, ignore the promise returned by foo, and then immediately resolve the new promise. The fact that foo does things later makes no difference to this promise.

Since foo already returns a promise (because it's an async function), there's no need to wrap it in a new one. You can change your code to:

async function x() {
  for (let i = 1; i <= 3; i++) {
    console.log("awaiting" + i);
    await foo();
    console.log("awaited" + i);
  }
}

async function foo() {
  for(let i = 1; i <= 2; i++){
    await sleep(1500);    
  } 
  console.log("finished");
}
function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

x();
Nicholas Tower
  • 72,740
  • 7
  • 86
  • 98
  • yeah thats still giving the wrong output as before – TDUK Feb 27 '21 at 22:50
  • Really? I've edited it to be a snippet, and it's outputting what you asked for when i run it. – Nicholas Tower Feb 27 '21 at 22:51
  • @TDUK Run the code snippet in the answer to see how it's working fine. Are you sure you didn't forget the `await` when trying this in your own code? – Bergi Feb 27 '21 at 22:52
  • shouldve mentioned this but there are multiple sleep's not just one, if that changes anything – TDUK Feb 27 '21 at 22:54
  • As long as they're awaited, there is no change other than to make it take longer. I've edited my snippet to include two sleeps per foo, and the output is still what you requested. – Nicholas Tower Feb 27 '21 at 22:59
  • Thanks man been trying to figure this out for ages but it turns out the problem was that the foo in x was actually a function expression – TDUK Feb 27 '21 at 23:07