事件循环(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

执行结果为:

✨✨✨✨✨✨✨✨✨✨

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

相关推荐
DevNote_16 分钟前
1C1G 服务器从零配置实录(附完整命令)
linux·运维·服务器·javascript·adb·ssh·gmssh
Dovis(誓平步青云)21 分钟前
切换语言后按钮被截断,本地化审计怎样发现长度风险
开发语言·前端·javascript·人工智能·机器学习·华为·harmonyos
CappuccinoRose29 分钟前
拖拽交互体系
前端·javascript·css·html·交互·1024程序员节
开开心心就好30 分钟前
免安装PDF盖章工具,透明度和位置可调
运维·服务器·前端·javascript·pdf·ocr·1024程序员节
2501_944521599 小时前
Ramda 跨端三方库仓颉适配全流程
开发语言·javascript·flutter·php
Ken_111511 小时前
小体积附件下载正常,大附件下载异常
javascript
变与不变80611 小时前
jQuery怎么使用
前端·javascript
paopaokaka_luck11 小时前
流浪动物救助与收养系统(DeepSeek AI对话、 ECharts多维分析、救助流程衔接、领养与回访衔接、 捐赠确认与公示、志愿者协作)
java·前端·javascript·人工智能·mysql·echarts·推荐算法
仰望.12 小时前
vue 表格组件 vxe-table 树表格懒加载支持拖拽排序的详细用法
前端·javascript·vue.js·vxe-table
程序员初一14 小时前
我把跑了两年 WordPress 的机器重装了一遍,顺便把面板卸了
javascript