📅  最后修改于: 2023-12-03 15:01:40.823000             🧑  作者: Mango
JavaScript 的事件循环机制是 JavaScript 的重要部分之一,在理解 JavaScript 的异步编程方面扮演了关键角色。事件循环机制可以让某个 JavaScript 代码块异步执行而不会阻塞主线程,从而使 Web 应用程序变得更加灵活和响应。在事件循环机制中,有两种主要的任务类型:微任务和宏任务。
宏任务就是指 JavaScript 执行栈中的任务,包括从事件循环队列中取出的任务(如在 setTimeout 中传递的函数)和用户输入事件(如点击事件)等。宏任务通常是异步执行的,因为它们被放在事件队列中并等待执行。
在执行宏任务时,JavaScript 会将一个宏任务执行完毕后才会去检查待处理的微任务队列,如果有微任务就会执行微任务。因此,在执行宏任务期间产生的微任务会在下一个事件循环中执行。下面是一个例子:
console.log("1");
setTimeout(function() {
console.log("2");
}, 0);
console.log("3");
上述代码的输出结果将是:“1”,“3”,“2”,因为在执行完“1”和“3”之后,setTimeout 中传递的函数被放入了事件队列,等待执行。当执行完当前宏任务时,JavaScript 会检查微任务队列并执行微任务。由于我们的例子中没有微任务,因此 JavaScript 继续处理事件队列中的下一个宏任务,即 setTimeout 中传递的函数,输出“2”。
微任务在概念上和宏任务类似,但是微任务比宏任务优先级更高,在事件循环机制中的位置也更靠前,因此在 JavaScript 第一次执行完宏任务后会首先检查微任务队列,如果有微任务则执行微任务。简而言之,微任务就是在当前宏任务执行完毕后需要立即执行的任务。
常见产生微任务的场景有:
下面是一个例子:
console.log("1");
setTimeout(function() {
console.log("2");
}, 0);
Promise.resolve().then(function() {
console.log("3");
});
console.log("4");
上述代码的输出结果将是:“1”,“4”,“3”,“2”,因为在执行完“1”和“4”之后,Promise.then 中的函数被放入微任务队列,等待执行。此时,JavaScript 检查微任务队列并执行微任务,输出“3”。由于该微任务执行完毕后并没有再次产生微任务,因此 JavaScript 继续处理事件队列中的下一个宏任务,即 setTimeout 中传递的函数,输出“2”。
微任务和宏任务的执行顺序是在任何情况下都要遵循的,这也是 JavaScript 事件循环机制中的重要一环。为了更好地遵循执行顺序,可以使用 Promise.resolve().then() 方式创建一个微任务。值得注意的是,如果在一个微任务处理期间产生了另外的微任务,则这些新的微任务会被插入到等待的微任务队列中,并在当前微任务完成后立即执行。
总结一下: