Can you find the difference between the two code snippets below:
function handleClick1() { setTimeout(handleClick1, 0); } function handleClick2() { Promise.resolve().then(handleClick2); }
If you are not able to identify the implications of choosing one over the other, then this blog post will teach you something new.
setTimeout is for scheduling a callback after a certain amount of time. Promise.resolve().then will do the same thing effectively, but internally both are different. The latter returns a promise, that is already resolved. Calling then(callback) on that promise will schedule callback to be executed.
So both the above functions call themselves recursively with minimal delay. The difference is that callback from setTimeout is placed in macrotask queue and a callback from a promise.then() is placed in microtask queue. How the event loop treats items from these two queues is what makes the above 2 code snippets the difference.
All an event loop does is while there are tasks to perform, it performs them and then sleeps and waits for other tasks.
Macrotasks (or simply tasks) include functions responsible for work such as:
among others...
After the execution of a task picked from the task queue, the event loop performs a microtask checkpoint. The algo for which is something like:
While microtask queue is not empty, pick the oldest task from microtask queue and execute it.
What this means is that if a microtask enqueues another microtask that task will be executed before the next macrotask. And since UI rendering is a macrotask, it will never be executed by the event loop.
Here is a demo for the above: JS Bin demo. An infinite animation is running. If we trigger handleClick1 then we add some processing to the main thread, but the animation still renders correctly. But if we trigger handleClick2 the animation stops.
I have added the variable totalCount, so we can break before the page crashes. But what is noticeable is that once the microTask loop is started, the UI becomes unresponsive for some time.. Because tasks like rendering, reacting to DOM etc. will only be executed after the microtask queue is empty.
This makes handleClick1 from the above code snippet a safer choice. Hope the blog helped explain one fundamental difference between microtasks and macrotasks.
The above is the detailed content of UI Blocking behaviour: microtasks vs macrotasks. For more information, please follow other related articles on the PHP Chinese website!