-1

I am trying to get a for loop to wait until it's resolved.

This is where I am but it's not working...

function myotherfunction() {
  // do something
  console.log("myotherfunction");
}
    
async function  myfunction() {
  var arr = ['one', 'two', 'three'];
  for (let i = 0; i < arr.length; i++) {
    await new Promise(resolve => {
      myotherfunction();
      console.log('done');
    });
  }
}

myfunction()

How to I fix my syntax?

Not A Bot
  • 2,474
  • 2
  • 16
  • 33
  • your other function should return an promise so you can await it like `await myotherfunction()` – bill.gates Nov 02 '20 at 11:54
  • pretty much every async function returns a promise these days, so you don't have to explicitly create a Promise and wrap your function inside it. – Akash Sarode Nov 02 '20 at 12:01
  • Note that these are also missing either the "function" keyword or an arrow. – Scott Sauyet Nov 02 '20 at 12:01
  • Do not use [the explicit promise constructor antipattern](https://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it). You're suffering because of it - you're never resolving the promise you yourself crete. Instead, all you need is `await myotherfunction();` without wrapping in a promise explicitly. – VLAZ Nov 02 '20 at 12:03

3 Answers3

0

Refactor your code such that myotherfunction function returns a promise so that you can await it inside the loop.

myotherfunction() {
  return new Promise((resolve, reject) => {
    
    // Resolve on some condition
    return resolve();
  });
}

async myfunction() {
  var arr = ['one', 'two', 'three'];
  for (let i = 0; i < arr.length; i++) {
    await myotherfunction();
  }
}
Kunal Mukherjee
  • 5,775
  • 3
  • 25
  • 53
0

Your await statement makes the function it is in go to sleep until the promise you pass it resolves.

That promise never calls resolve(), so it goes to sleep forever.

You need to call resolve.


Of course, you shouldn't do that until whatever you are waiting for has happened, so you should probably be removing that promise entirely and returning one from myotherfunction.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
0

Making the other function async probably does what you want:

async function myotherfunction(n) {
  return new Promise(resolve => setTimeout(() => resolve(`found ${n}`), 300))
}

async function myfunction() {
  var arr = ['one', 'two', 'three'];
  for (let i = 0; i < arr.length; i++) {
      const result = await myotherfunction(arr[i]);
      console.log(`${result} - done`);
  }
  console.log('completed')
}

myfunction()

By awaiting the result of that function, you get the rest of your function (the console.log statement and the remainder of the for-loop) to run after the current asynchronous statement has completed.

If instead, you wanted all three asynchronous calls to execute together and then resume the rest of your function then, you should investigate Promise.all.

Scott Sauyet
  • 49,207
  • 4
  • 49
  • 103
  • Where do I add some code here thats not a setTimeout? // async function myotherfunction(n) { return new Promise(resolve => setTimeout(() => resolve(`found ${n}`), 300)) } – jonnycode2020 Nov 02 '20 at 12:25
  • The `setTimeout` was just an illustration, so you could see it in the console. By declaring `myotherfunction` as `async`, it will automatically return a Promise. If you return a non-Promise value, it will act as though you returned `Promise.resolve(thatValue)`. You can do what you choose inside that function, returning a Promise to eventually be resolved/rejected, returning a plain value, or returning an already resolved/rejected Promise. – Scott Sauyet Nov 02 '20 at 13:15