在事件循环中,微任务比宏任务具有更高的优先级,因此微任务会先于宏任务执行。
具体来说,当一个宏任务执行完毕后,会立即检查微任务队列中是否有待执行的微任务。如果有,则按照先进先出的顺序依次执行所有的微任务,直到微任务队列为空。然后才会执行下一个宏任务。
这意味着,即使有多个宏任务在排队等待执行,在执行下一个宏任务之前,都会先执行完所有的微任务。
举个例子来说,假设有以下代码:
console.log('1');
setTimeout(function() {
console.log('2');
}, 0);
Promise.resolve().then(function() {
console.log('3');
});
console.log('4');
执行顺序是:
- 执行同步代码,输出1;
- 遇到setTimeout,将其回调函数放入宏任务队列;
- 遇到Promise,将其回调函数放入微任务队列;
- 输出4;
- 当前宏任务执行完毕,执行微任务队列中的所有微任务,输出3;
- 执行浏览器UI线程的渲染工作;
- 检查是否有Web Worker任务,如果有则执行;
- 执行下一个宏任务,取出setTimeout的回调函数,输出2。
因此,在这个例子中,微任务先于宏任务执行,输出顺序是1、4、3、2。
=========================================================================
在JavaScript中,常见的宏任务包括:
整体的script代码:当浏览器解析HTML页面时,会先加载并执行整体的script代码。整体的script代码执行完毕后,才会继续执行其他的宏任务和微任务。
setTimeout和setInterval回调函数
DOM事件处理函数:DOM事件处理函数是指在DOM元素上注册的事件回调函数,比如点击事件、鼠标移动事件、键盘事件等。当用户与页面进行交互时,浏览器会触发相应的事件,并执行对应的事件处理函数。这些事件处理函数属于宏任务,会在它们所属的事件循环迭代中执行。
XMLHttpRequest回调函数:
XMLHttpRequest回调函数指的是通过XMLHttpRequest对象发送请求后,服务器响应返回时所触发的回调函数。
XMLHttpRequest是用于在浏览器中发送HTTP请求的对象,可以用于异步加载数据或与服务器进行交互。当发送请求时,可以为XMLHttpRequest对象指定一个回调函数,用于处理服务器返回的响应数据。
以下是一个使用XMLHttpRequest发送异步请求的示例:
const xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.example.com/data", true);
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
const response = JSON.parse(xhr.responseText);
console.log(response);
}
};
xhr.send();
而常见的微任务包括:
Promise回调函数(.then.catch都是微任务)