promise with no setTimeout()
console.log('Prmoise start');
const lotteryPromise = new Promise(function (resolve, reject) {
if(Math.random() >= 0.5) {
resolve('You won the lottery');
} else {
reject(new Error('You lost your money'));
}
});
lotteryPromise.then(res => console.log(res)).catch(err => console.error(err));
console.log('Promise end');
promise with setTimeout()
console.log('Prmoise start');
const lotteryPromise = new Promise(function (resolve, reject) {
setTimeout( () => {
if(Math.random() >= 0.5) {
resolve('You won the lottery');
} else {
reject(new Error('You lost your money'));
}
},2000);
});
lotteryPromise.then(res => console.log(res)).catch(err => console.error(err));
console.log('Promise end');
I don’t understand the usage of setTimeout() wrap in promise? Even without the timer wrap the promise is asynchronously executing right ? Settimeout is just delaying the code executing ? other than this is there anything else I am missing? By the I know how call stack, micro tasks and callback queue works….
4
Answers
Promise.resolve schedules a microtask and the setTimeout schedules a macrotask. And the microtasks are executed before running the next macrotask.
By adding a timer to your code, you are further confirming that the code inside the promise is running asynchronously. This is just to mimic the behavior of real-life examples for asynchronous operations like fetching data.
It waits for 2 seconds then perform your operations and resolve afterwards.
You’re addressing this problem backwards. You should be asking: What is the point of using a promise without
setTimeout
?The purpose of a promise is to manage asynchronous code in a standard way.
The purpose of the
new Promise
constructor is to create a promise for asynchronous code which doesn’t use promises natively.In your first chunk of code, there is nothing asynchronous about the function you pass to
Promise()
. It’s a pointless promise.In your second chunk of code, the
setTimeout
is asynchronous but you’ve no way to know when it is finished (other than modifying the callback you pass to it). Usingnew Promise
with it allows you to use the promise object to do something when thesetTimeout
is complete.That said, there’s no obvious reason to use
setTimeout
or promises at all for this example. It’s entirely contrived to demonstrate how promises work, not to be a practical example of when you should use a promise or a timeout.A slight miss conception of promises, is that there async. But there really only just a contract, that is then placed into a queue that will get processed before the next event loop. Very useful for writing async code, much nicer than callbacks.
Below is a simple example with 2 promises, 1 promise is not doing anything async, the other is doing a simple async sleep. That async sleep is very important, because this allows the browser to process the next event loop. If you take this sleep out, and re-run, watch how the browser will hang.
Now in the above it might seem strange why does removing that sleep cause the browser to hang.
Browsers use something called an event loop, this is responsible for getting things like mouse clicks, timers etc, and dispatching them to listeners. This is very similar to how cooperative multi-tasking OS’s work, think Window 3.11.
So, inside the browser TAB there will be an Event Loop running, doing something like ->
That
getNextMessage
above will efficiently wait for some event, timer, mouse move, etc etc. So it won’t be wasting CPU resources, even thought it’s in this tight LOOP.So what does this have to do with promises you may ask. Well this bit is where the
microtask
comes in, unlikemacrotask
like a timer, that the browser can dispatch from, there basically stuck into a queue that get drained before the nextmacrotask
is processed.So if you had promises that’s only did stage (3), constantly the browser gets stuck at (3), as such does not get any chance to process any
macrotasks
, IOW: The browser HANGS!!Hopefully that makes sense, and I’ve used the correct terminology etc.
ps. Very similar to 3.11, a badly written app that never gave chance for the OS to process it’s event loop, would in fact hang the whole OS. Strange how these things come round again.. 🙂