DEV Community

Discussion on: Simple Explanation of Async-Await in Javascript

Collapse
 
peerreynders profile image
peerreynders
function solveC() {
  const getB = () => {
    setTimeout(() => {return 2;}, 500); 
  }
  const A = 1;
  const B = getB();
  const C = A + B;

  return C;
}

console.log(solveC()); // NaN
Enter fullscreen mode Exit fullscreen mode

The reason solveC returns NaN is because getB will always return undefined.
And 1 + undefined is NaN.
This has nothing to do with the setTimeout.

And as it happens Promises and setTimeout are scheduled on separate queues.

setTimeout is scheduled on the task queue while promises are scheduled on the micro-task queue.

However promises are often used to get a value from setTimeout to a consumer

function solveC() {
  const getB = () => {
    const executor = (resolve, _reject) => {
      setTimeout(() => resolve(2), 500)
    };
    return new Promise(executor); 
  }
  const a = 1;
  const showC = b => {
    console.log(a + b);
  };

  getB().then(showC);
}

solveC(); // returns `undefined` but `3` displays eventually
Enter fullscreen mode Exit fullscreen mode

With async/await one can write

async function solveC() {
  const getB = () => {
    const executor = (resolve, _reject) => {
      setTimeout(() => resolve(2), 500)
    };
    return new Promise(executor); 
  }
  const a = 1;
  const b = await getB();
  console.log(a + b);
}

solveC(); // returns `Promise(<pending>)` and `3` displays eventually
Enter fullscreen mode Exit fullscreen mode

or perhaps

async function solveC() {
  const getB = () => {
    const executor = (resolve, _reject) => {
      setTimeout(() => resolve(2), 500)
    };
    return new Promise(executor); 
  }
  const a = 1;
  const b = await getB();
  return a + b;
}

solveC().then(c => console.log(c)); // Displays `3` eventually
Enter fullscreen mode Exit fullscreen mode

Resources:

Collapse
 
lindaojo profile image
Linda

I understand, thank you for the detailed correction 💙

Collapse
 
peerreynders profile image
peerreynders • Edited

Your correction

function solveC() {
    const getB = () => {
      const executor = (resolve, _reject) => {
        setTimeout(() => resolve(2), 100);
      };
      return new Promise(executor); 
    }
    const a = 1;

    const b = getB(); // b = Promise(<pending>)

    const c = a + b;  // c = 1 + Promise(<pending>)

    console.log(C);   // Displays "1[object Promise]"
}

solveC(); // returns `undefined`
Enter fullscreen mode Exit fullscreen mode

Simply replaces c = 1 + undefined with c = 1 + Promise<pending> - which similarly doesn't work.
The displayed result shows that JavaScript simply concatenated them - with really isn't useful.

Perhaps you meant:

function solveC() {
  const getB = () => {
    const executor = (resolve, _reject) => {
      setTimeout(() => resolve(2), 500); // Promise resolves to `2` here after ~500ms
    };
    return new Promise(executor);
  };
  const a = 1;
  const promiseB = getB();
  promiseB.then((b) => { // b resolves to `2`
    const c = a + b;     // c = 1 + 2
    console.log(c);      // displays `3`
  });
}

solveC(); // returns `undefined`
Enter fullscreen mode Exit fullscreen mode

This may be of interest:

Thread Thread
 
lindaojo profile image
Linda

No, that was my intention; to show what could go wrong if 'B' was delayed.

Thank you for the resources.

Thread Thread
 
peerreynders profile image
peerreynders • Edited

The point is b isn't delayed.

b is a promise, not a number.

What is delayed is the fulfillment of the promise to a number. In TypeScript this is immediately flagged as an error.

type Resolve = (v: number) => void;

function solveC() {
  const getB = () => {
    const executor = (resolve: Resolve, _reject: unknown) => {
      setTimeout(() => resolve(2), 500);
    };
    return new Promise(executor);
  };
  const a = 1;
  const b = getB();
  const c = a + b; // Error: Operator '+' cannot be applied to types '1' and Promise<number>

  console.log(c);
}
solveC();
Enter fullscreen mode Exit fullscreen mode

link

This is simply a programming error caused by type confusion

async/await doesn't "fix" this error.

async/await is simply syntax sugar so you don't have to deal with the promise directly. But await only works on promises - so you have to be aware that you are dealing with promises as it is the case with getB().

I'm not advocating the use of TypeScript here but I do think it is essential to "think in types" even when you are using a dynamically typed language.

PS: await has its own challenges: