DEV Community

Kenneth Lum
Kenneth Lum

Posted on

async / await concepts

To a traditional programmer, async / await can be tricky. Here are some key concepts:

  1. There cannot be any await inside of a function if this function is not declared as an async function.
  2. You can think of it this way: this async function returns to you immediately, and what does it return? It returns a promise that will be resolved or rejected later.
  3. Inside of the async function, the code will run, until it hits an await. Don't think of this await as "waiting", but more like a notifyMeOfTheValueWhenReady or aValueThatWillBeReady. You can even read it as stopHereAndGiveMeTheValueWhenReady.
  4. To be more precise, the promise isn't returned to the caller until the first await is reached. Typically you will have at least one await inside an async function, or else you wouldn't use an async function in the first place. You can see in the examples below to verify the case: inside the async function, the code runs until the first await, then the promise is returned to the caller. This usually does not matter, but it may be good to know.
  5. This await is like a "set it and forget it". It is similar to setting an observer, if you are familiar with the observer pattern. Or you can think of it as setting a callback function. The await is followed by a promise, like await p; You can think of it as a .then(v => { ... }), so the value v is what await p will become in the future.
  6. When the execution of code reaches this await, after the "set it and forget it", nothing is done. The code does not go onto the next line until this "future value", or promise is resolved or rejected.
  7. We can use price = await getStockPrice(); or displayStockPrice(await getStockPrice());. In the first case, that await reads like notifyMeOfTheValueWhenReady. In the second case, the await reads like aValueThatWillBeReady. For both cases, reading it as stopHereAndGiveMeTheValueWhenReady goes well. In the second case, the await cause the async function code to stop there, until a value is obtained, and then displayStockPrice() is called.

Example 1

In the following, try and figure out the order of the lines are displayed.

Note that $(document).ready(function() { ... }); is just jQuery's way of running the code when the DOM is ready in the jsfiddle environment.

https://jsfiddle.net/kwtomj59/

  console.log("Running the program");

  async function foo() {
    console.log("I am running at Point A of the async function");
    return 123;
  }

  foo().then((v) => {
    console.log("finally I get the value from the async function", v);
  });

  console.log("This is after calling the async function");
Enter fullscreen mode Exit fullscreen mode

Example 2

What about the following? Note that when the big loop is running, the UI of that input box is not reacting.

https://jsfiddle.net/odr4sz58/

  console.log("Running the program");

  async function foo() {
    let a = 0;

    for (let i = 0; i < 1000000000; i++) {
      a += Math.random() > 0.5 ? 1 : -1;
    }
    console.log("I am running at Point A of the async function");

    return a;
  }

  foo().then((v) => {
    console.log("finally I get the value from the async function, and it is ", v);
  });

  console.log("This is after calling the async function");
Enter fullscreen mode Exit fullscreen mode

Example 3

Since the console.log is not executed until later, we can use alert to see the immediate message:

https://jsfiddle.net/odr4sz58/1/

It is just the above program with the console.log replaced with alert.

Example 4

https://jsfiddle.net/hpj4tvy3/

  alert("Running the program");

  async function foo() {
    let a = 0;

    const foo = await (new Promise(resolve => setTimeout(() => resolve(123), 0)));

    for (let i = 0; i < 1000000000; i++) {
      a += Math.random() > 0.5 ? 1 : -1;
    }
    alert("I am running at Point A of the async function");

    return [a, foo];
  }

  foo().then((v) => {
    alert(`finally I get the value from the async function, and it is ${JSON.stringify(v)}`);
  });

  alert("This is after calling the async function");
Enter fullscreen mode Exit fullscreen mode

Example 5

Finally, here is an example of the fn(await ...) pattern. What is the order of the messages being displayed?

https://jsfiddle.net/yb0th3cw/

  alert("Running the program");

  async function foo() {
    let a = 0;

    alert(await (new Promise(resolve => setTimeout(() => resolve(123), 0))));

    for (let i = 0; i < 1000000000; i++) {
      a += Math.random() > 0.5 ? 1 : -1;
    }
    alert("I am running at Point A of the async function");

    return a;
  }

  foo().then((v) => {
    alert(`finally I get the value from the async function, and it is ${JSON.stringify(v)}`);
  });

  alert("This is after calling the async function");
Enter fullscreen mode Exit fullscreen mode

Top comments (0)