0

I am trying to improve my understanding of asynchronous JavaScript. To do this I have made a function that can take a long time to complete, which would completely block any other code from executing.

To test this, the function counts up. the first call counts from 1 to 10000000. The second call counts from 10 to 100.

CODE

async function LongTask(from, to) {
    //Count up
    let myNum = from
    console.log(`counting from ${myNum} to ${to}`)
    let start = new Date();

    while (myNum != to) {
        //console.log(`myNum: ${myNum}`);
        await myNum++;

    }
    let end = new Date();
    console.log(`counting from ${from} to ${to} done in ${end - start}ms!`);
}

//2 functions that take some time to finish
LongTask(1, 10000000);
LongTask(10, 100);

//Do unrelated stuff
console.log("Hello World!");

OUTPUT

counting from 1 to 10000000
counting from 10 to 100
Hello World!
counting from 10 to 100 done in 2ms!
counting from 1 to 10000000 done in 40389ms!

I managed to get it so that 10 to 100 will finish first due to it being faster. However, I get a warning on line 10 await myNum++; saying 'await' has no effect on the type of this expression. Removing the await keyword results in code blocking making it so that the 10 to 100 call of the function will have to wait for the much longer, unrelated 1 to 10000000 call to finish before being called.

Am I misunderstanding how asynchronous JavaScript works and is there a better way to ensure the 10 to 100 call finishes first?

Curtis_L
  • 7
  • 2
  • 6
  • 3
    `await` only makes sense when used with Promises. You can't really await anything else, it'll just yield the value and continue. – tkausl Feb 05 '23 at 11:50
  • Think you can do multiple async await using Promise.all with async await, try it – ksd030687d Feb 05 '23 at 11:53
  • 2
    counting isn't very good for this type of illustration because they are both basically instantaneous. Use a [sleep function](https://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep) to ensure that one takes longer than the other. [jsfiddle](https://jsfiddle.net/zc7nsu2k/) – pilchard Feb 05 '23 at 11:53

1 Answers1

0

You can only await a Promise which your function (and every async function) returns. You'll have to await both promises at some point in order to make sure the program does not exit before the promises resolve.

You can use Promise.all() to await multiple promises. I altered your example to await a predefined time span to illustrate how this works, as I then exactly know when I expect a function to finish.

(async() => {
  async function LongTask(ms) {
    console.log(`starting task that will take ${ms} milliseconds`)
    await waitFor(ms);
    console.log(`ended task that took ${ms} milliseconds`);
  }

  async function waitFor(ms) {
    return new Promise((resolve, reject) => setTimeout(() => resolve(), ms))
  };

  //2 functions that take some time to finish
  const start = new Date();
  console.log(`Calling both functions at ${start}`)
  const countToSmallNumberPromise = LongTask(4000);
  const countToLargeNumberPromise = LongTask(1000);

  //Do unrelated stuff
  console.log("Hello World!");
  // await both promises to make sure they finish before the program finishes
  await Promise.all([countToLargeNumberPromise, countToSmallNumberPromise])
  const end = new Date();
  // program will end after approx. 4 seconds (at least 4 seconds), so both functions actually run in parallel 
  // (that's actually not correct, there is no real parallelism here, as Node or your browser are single-threaded)
  // To be correct: they run concurrently, not in parallel.
  console.log(`Ending program at ${end}. Program ran for ${end - start} milliseconds`);
})();

FYI: Difference between concurrent and in parallel

Mushroomator
  • 6,516
  • 1
  • 10
  • 27
  • Your `Promise.all` isn't doing anything here since you aren't capturing the return of it and the `log` calls are included in the `LongTask`. (remove it and the output will be the same) – pilchard Feb 05 '23 at 12:06
  • Yes you're right, noticed it right away :D I've corrected the program – Mushroomator Feb 05 '23 at 12:10