Why is Promise faster than setTimeout()? The following article will analyze the reasons for you. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to everyone.
Related recommendations: "javascript video tutorial"
Let's do an experiment. Which executes faster: an immediately resolved Promise or an immediate setTimeout
(that is, a setTimeout of 0 milliseconds)?
Promise.resolve(1).then(function resolve() { console.log('Resolved!'); }); setTimeout(function timeout() { console.log('Timed out!'); }, 0); // 'Resolved!' // 'Timed out!'
promise.resolve(1)
is a static Function that returns an promise
that resolves immediately. setTimeout(callback, 0)
Execute the callback function with a delay of 0 milliseconds
.
We can see that 'Resolved!'
is printed first, and then Timeout completed!
is printed. The promise that is resolved immediately is faster than the immediate setTimeout
.
is because Promise.resolve(true).then(...)
was called before setTimeout(..., 0)
, so the Promise process Will it be faster? Fair question.
So, let’s change the experimental conditions slightly, and then call setTimeout(..., 0)
:
setTimeout(function timeout() { console.log('Timed out!'); }, 0); Promise.resolve(1).then(function resolve() { console.log('Resolved!'); }); // 'Resolved!' // 'Timed out!'
setTimeout(..., 0 )
is called before Promise.resolve(true).then(...)
. However, Resolved!
is printed first and then 'Timed out!'
.
Why is this?
Questions related to asynchronous JS can be answered by studying the event loop. Let’s review the main components of how asynchronous JS works.
[External link image transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the image and upload it directly (img-Lt9zVHTf-1611275604640)(/img/bVcMQaI)]
Call stack is a LIFO (last in first out) structure that stores the execution context created during code execution. Simply put, the call stack executes these functions.
Web api is where asynchronous operations (fetch requests, promises, timers) and their callbacks wait for completion.
**task queue (task queue) is a FIFO (first in, first out)** structure, which saves the callbacks of asynchronous operations that are ready to be executed. For example, the callback function of setTimeout()
that times out or the click button event handler that is ready to be executed are queued in the task queue.
**job queue (job queue)** is a FIFO (first in, first out) structure, which saves the callbacks of promise
that are ready to be executed. For example, a completed promise's resolve
or reject
callback is enqueued in the job queue.
Finally, the event loop permanently monitors whether the call stack is empty. If the call stack is empty, the event loop looks at the job queue or task queue and dispatches any callbacks that are ready to be executed onto the call stack.
Let’s look at this experiment from the perspective of the event loop, and I will analyze the code execution step by step.
A) The call stack executes setTimeout(..., 0)
and schedules a timer, timeout()
The callback is stored in the Web API:
[External link image transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the image and upload it directly (img-SLk0AUa5-1611275604642)(/img/bVcMQdg)]
[External link image The transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-Zr7usYTK-1611275604643)(/img/bVcMQc9)]
B) Call stack execution Promise.resolve (true).then(resolve)
And arrange a promise
solution. resolved()
The callback is stored in the Web API:
[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-JTwSnLYS- 1611275604646)(/img/bVcMQdh)]
[The external link image transfer failed. The source site may have an anti-hotlink mechanism. It is recommended to save the image and upload it directly (img-k5cRhqzN-1611275604648)(/img/bVcMQdi )]
C) The promise is resolved immediately and the timer is executed immediately. In this way, the timer callback timeout()
enters the task queue, and the promise
callback resolve()
enters the job queue
[External link picture transfer Failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-iMfLB2YJ-1611275604649)(/img/bVcMQdS)]
D) Now comes the interesting part: job queue (microtask) ) has a higher priority than the task queue (macro task). The event loop takes the promise callback resolve()
from the job queue and puts it into the call stack. Then, the call stack executes the promise callback resolve()
:
[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img-nnqfgoo1 -1611275604650)(/img/bVcMQey)]
E) Finally, the event loop dequeues the timer callback timeout()
from the task queue onto the call stack. Then, the call stack executes the timer callback timeout()
:
[The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly (img- Fj54WaI0-1611275604650)(/img/bVcMQeB)]
The call stack is empty and the execution of the script has been completed.
Why do immediately resolved promises process faster than immediate execution timers?
Due to the existence of event loop priorities, compared to the task queue (which stores the timeout's setTimeout()
callback), the job queue (which stores the implemented Promise
Callback) has higher priority.
Original address: https://dmitripavlutin.com/javascript-promises-settimeout/
Author: Milos Protic
Translation address: https://segmentfault .com/a/1190000038769853
For more computer programming related knowledge, please visit: Programming Video! !
The above is the detailed content of An in-depth analysis of why Promise is faster than setTimeout(). For more information, please follow other related articles on the PHP Chinese website!