functionsolveC(){constgetB=()=>{setTimeout(()=>{return2;},500);}constA=1;constB=getB();constC=A+B;returnC;}console.log(solveC());// NaN
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
functionsolveC(){constgetB=()=>{constexecutor=(resolve,_reject)=>{setTimeout(()=>resolve(2),500)};returnnewPromise(executor);}consta=1;constshowC=b=>{console.log(a+b);};getB().then(showC);}solveC();// returns `undefined` but `3` displays eventually
With async/await one can write
asyncfunctionsolveC(){constgetB=()=>{constexecutor=(resolve,_reject)=>{setTimeout(()=>resolve(2),500)};returnnewPromise(executor);}consta=1;constb=awaitgetB();console.log(a+b);}solveC();// returns `Promise(<pending>)` and `3` displays eventually
or perhaps
asyncfunctionsolveC(){constgetB=()=>{constexecutor=(resolve,_reject)=>{setTimeout(()=>resolve(2),500)};returnnewPromise(executor);}consta=1;constb=awaitgetB();returna+b;}solveC().then(c=>console.log(c));// Displays `3` eventually
functionsolveC(){constgetB=()=>{constexecutor=(resolve,_reject)=>{setTimeout(()=>resolve(2),100);};returnnewPromise(executor);}consta=1;constb=getB();// b = Promise(<pending>)constc=a+b;// c = 1 + Promise(<pending>)console.log(C);// Displays "1[object Promise]"}solveC();// returns `undefined`
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:
functionsolveC(){constgetB=()=>{constexecutor=(resolve,_reject)=>{setTimeout(()=>resolve(2),500);// Promise resolves to `2` here after ~500ms};returnnewPromise(executor);};consta=1;constpromiseB=getB();promiseB.then((b)=>{// b resolves to `2`constc=a+b;// c = 1 + 2console.log(c);// displays `3`});}solveC();// returns `undefined`
What is delayed is the fulfillment of the promise to a number. In TypeScript this is immediately flagged as an error.
typeResolve=(v:number)=>void;functionsolveC(){constgetB=()=>{constexecutor=(resolve:Resolve,_reject:unknown)=>{setTimeout(()=>resolve(2),500);};returnnewPromise(executor);};consta=1;constb=getB();constc=a+b;// Error: Operator '+' cannot be applied to types '1' and Promise<number>console.log(c);}solveC();
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.
The reason
solveCreturnsNaNis becausegetBwill always returnundefined.And
1 + undefinedisNaN.This has nothing to do with the
setTimeout.And as it happens
PromisesandsetTimeoutare scheduled on separate queues.setTimeoutis scheduled on the task queue while promises are scheduled on the micro-task queue.However promises are often used to get a value from
setTimeoutto a consumerWith async/await one can write
or perhaps
Resources:
I understand, thank you for the detailed correction 💙
Your correction
Simply replaces
c = 1 + undefinedwithc = 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:
This may be of interest:
No, that was my intention; to show what could go wrong if 'B' was delayed.
Thank you for the resources.
The point is
bisn't delayed.bis 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.
link
This is simply a programming error caused by type confusion
async/awaitdoesn't "fix" this error.async/awaitis simply syntax sugar so you don't have to deal with the promise directly. Butawaitonly works on promises - so you have to be aware that you are dealing with promises as it is the case withgetB().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:
awaithas its own challenges: