Microtasks are a crucial part of the JavaScript event loop, allowing developers to manage asynchronous operations efficiently. They are executed after the currently executing script and before any rendering or other tasks. Understanding how microtasks work is essential for writing performant and responsive applications. Below, we will explore various operations that create microtasks, along with practical examples, best practices, and common mistakes.
Microtasks are generally created by promises and certain APIs. They provide a way to schedule tasks that should be executed after the current operation completes but before the next rendering cycle. This makes them particularly useful for handling asynchronous operations in a predictable manner.
const myPromise = new Promise((resolve, reject) => {
resolve('Promise Resolved!');
});
myPromise.then((message) => {
console.log(message); // This runs as a microtask
});
console.log('End of script'); // This runs first
In the example above, the message "Promise Resolved!" is logged after "End of script" because the `.then()` callback is executed as a microtask.
const observer = new MutationObserver((mutationsList) => {
for (let mutation of mutationsList) {
console.log('DOM changed:', mutation);
}
});
observer.observe(document.body, { childList: true });
// Simulating a DOM change
document.body.appendChild(document.createElement('div'));
Here, the MutationObserver detects a change in the DOM and schedules the callback as a microtask, ensuring that it runs after the current script execution.
console.log('Before microtask');
queueMicrotask(() => {
console.log('Inside microtask');
});
console.log('After microtask');
This example demonstrates how to explicitly create a microtask using `queueMicrotask`. The output will show that "Inside microtask" is logged after "After microtask" but before any rendering.
In conclusion, understanding microtasks and their creation through promises, MutationObservers, and `queueMicrotask` is vital for effective JavaScript programming. By following best practices and avoiding common pitfalls, developers can ensure that their applications remain responsive and performant.