事件循环(Event Loop)

一、什么是Event Loop🤔

JavaScript是一门单线程语言,它一个时间只能做一件事;

在js代码运行的时候,会形成一个执行栈,每调用一个函数,就会把该函数的执行上下文放入执行栈;

另外还有任务队列存放待完成的任务,在js中,有同步任务异步任务 ,异步任务又分为宏任务微任务

因为script代码整体就是一个宏任务,因此事件循环先从一个宏任务开始,当执行完宏任务后,就从微任务队列拿微任务到执行栈中执行,当前微任务队列所有微任务执行完后,就执行宏任务队列的下一个宏任务;

然后重复这个操作,直到任务队列里的任务执行完,这个过程就叫事件循环。

二、宏任务和微任务📜

JavaScript 的事件分两种,宏任务 (macro-task)和微任务(micro-task)。

1. 宏任务

  • script
  • setTimeout
  • setInterval
  • setImmediate

2. 微任务

  • promise.then() promise.catch() 的回调cb
  • async await
  • mutationObserver ==> 监听DOM的改变
  • process.nextTick() ==> Node

关系: 微任务是包含在宏任务里面的,一个宏任务中,可以有多个微任务。

3. 执行顺序

  • 首先script代码块可以看做第一个宏任务,开始第一个Tick事件循环
  • 会先执行script代码块中的同步代码
  • 如果遇到宏任务,就放到宏任务队列中等待执行, 如果遇到微任务,放到微任务队列中
  • 当主线程执行完同步代码的时候,首先去微任务队列中清空当前事件循环的所有微任务(本轮事件循环Tick结束)
  • 如果还有异步的宏任务,那么就会进行循环执行上述的操作

三、来点例子🌰

eg1:

js 复制代码
const promise = new Promise((resolve, reject) => {
    console.log(1);
    resolve(5);
    console.log(2);
}).then(val => {
    console.log(val);
});

promise.then(() => {
    console.log(3);
});

console.log(4);

setTimeout(function() {
    console.log(6);
});

// 1  2  4  5  3  6

执行结果为: 1 2 4 5 3 6

eg2:

js 复制代码
async function async1() {
    console.log('async1 start')  
    await async2()      // await这一行,这个async2 同步执行的; await的下面,放到微任务队列
    console.log('async1 end') // 这一行,相当于放到.then()中  微1 
    console.log(666)
}
async function async2() {
    console.log('async2')
}

console.log('script start')  

setTimeout(function() {
    console.log('setTimeout') // 放到宏任务队列中 宏1 
}, 0)

async1();

new Promise(function(resolve) {
    console.log('promise1')
    resolve();
}).then(function() {
    console.log('promise2')  // 微任务  微2 
});
console.log('script end')

// script start 
// async1 start
// async2
// promise1
// script end
// async1 end
// 666
// promise2  (本轮tick结束)
// setTimeout

执行结果为:

✨✨✨✨✨✨✨✨✨✨

在本轮事件循环中的微任务比下一次的事件循环中的宏任务优先级高,也就是我们要将这轮的微任务都执行完毕,才能去执行下一个宏任务。

相关推荐
云水一下7 小时前
TypeScript 从零基础到精通(五):高级类型与泛型
前端·javascript·typescript
云水一下8 小时前
TypeScript 从零基础到精通(六):类型声明与模块化
javascript·typescript
xiaofeichaichai9 小时前
Map / Set / WeakMap / WeakSet
前端·javascript
有梦想的程序星空11 小时前
【环境配置】Vue3项目离线化本地部署echarts全攻略
前端·javascript·vue·echarts
薛先生_09911 小时前
vue-路由重定向
前端·javascript·vue.js
橘子星12 小时前
基于 ES6 语法的 NLP 任务模块化开发实践
前端·javascript
月光刺眼12 小时前
JS 底层执行机制探讨:执行上下文、变量提升与调用栈
前端·javascript
ZC跨境爬虫12 小时前
跟着 MDN 学 JavaScript day_1:什么是 JavaScript?
开发语言·前端·javascript·ecmascript
xiaofeichaichai12 小时前
Vue 响应式原理
前端·javascript·vue.js
提子拌饭13312 小时前
模态窗鸿蒙PC Electron框架实现技术详解 - 饮料含糖量应用案例分析
前端·javascript·华为·electron·前端框架·开源·鸿蒙