一文搞定事件循环

同步任务、异步任务、宏任务、微任务

js任务分为同步任务和异步任务;异步任务又分为宏任务和微任务

  • 同步任务:在主线程上按顺序执行,Promise属于同步任务。
  • 异步任务:异步任务不会立即执行,它们依赖事件循环进行调度。异步任务包含宏任务和微任务,它们在特定时间点被推入各自的任务队列中等待执行。
  • 宏任务 :常见的宏任务包括:script整体代码setTimeoutsetIntervalI/O操作UI交互事件postMessageMessageChannelsetImmediate
  • 微任务 :常见的微任务包括:Promise的回调(.then.catch.finally )、MutationObserver的回调process.nextTick

js执行顺序

同步任务------》微任务------》宏任务------》微任务------》宏任务------》...

一次事件循环

  1. 执行当前宏任务:事件循环首先从宏任务队列中取出第一个任务执行。
  2. 执行所有微任务:当前宏任务执行完毕后,事件循环会检查微任务队列,事件循环会一次执行队列中所有微任务,知道微任务队列清空。
  3. 渲染UI(如果需要):在浏览器环境中,一旦微任务队列清空,浏览器会检查是否需要执行UI渲染。通常,浏览器的UI渲染会在执行完所有微任务之后,下一个宏任务开始之前进行。
  4. 继续下一个宏任务:完成当前宏任务、所有微任务以及可能的UI渲染之后,事件循环会回到第一步,从宏任务队列中取出下一个任务,开始新一轮的执行。

实践

js 复制代码
;(() => {
	console.log(1)
	setTimeout(() => {
		console.log('setTimeout 1')

		Promise.resolve().then(() => {
			console.log('promise 1')
		})
	})
	setTimeout(() => {
		console.log('setTimeout 2')
		Promise.resolve().then(() => {
			console.log('promise 2')
		})
	})

	Promise.resolve().then(() => {
		console.log('promise 3')
		Promise.resolve().then(() => {
			console.log('promise 4')
		})
	})

	Promise.resolve().then(() => {
		console.log('promise 5')
		Promise.resolve().then(() => {
			console.log('promise 6')
		})
	})
	console.log(7)
})()

执行步骤解析

  1. javascript整体代码注册了一个宏任务,放入宏任务队列
  2. 此时执行栈/主线程空闲,事件循环从宏任务队列中取出一个宏任务执行。
  3. console.log(1)为同步任务,会立即执行,输出1
  4. setTimeout(() => { console.log('setTimeout 1') Promise.resolve().then(() => { console.log('promise 1') }) })注册一个宏任务,放入宏任务队列
  5. setTimeout(() => { console.log('setTimeout 2') Promise.resolve().then(() => { console.log('promise 2') }) })注册一个宏任务,放入宏任务队列
  6. Promise.resolve().then(() => { console.log('promise 3') Promise.resolve().then(() => { console.log('promise 4') }) })注册一个微任务,放入微任务队列
  7. Promise.resolve().then(() => { console.log('promise 5') Promise.resolve().then(() => { console.log('promise 6') }) })注册一个微任务,放入微任务队列
  8. console.log(7)为同步任务,立即执行,输出7
  9. 主线程空闲,检查微任务队列,取出一个微任务Promise.resolve().then(() => { console.log('promise 3') Promise.resolve().then(() => { console.log('promise 4') }) })执行then回调,输出promise 3
  10. Promise.resolve().then(() => { console.log('promise 4') })注册一个微任务,放入微任务队列队尾。
  11. 取出下一个微任务Promise.resolve().then(() => { console.log('promise 5') Promise.resolve().then(() => { console.log('promise 6') }) })执行then回调,输出promise 5
  12. Promise.resolve().then(() => { console.log('promise 6') })注册一个微任务,放入微任务队列队尾。
  13. 取出下一个微任务Promise.resolve().then(() => { console.log('promise 4') })执行then回调,输出promise 4
  14. 取出下一个微任务Promise.resolve().then(() => { console.log('promise 6') })执行then回调,输出promise 6
  15. 此时微任务队列清空,无UI渲染需求,开启下一轮事件循环,执行下一个宏任务。取出一个宏任务setTimeout(() => { console.log('setTimeout 1') Promise.resolve().then(() => { console.log('promise 1') }) })输出setTimeout 1
  16. Promise.resolve().then(() => { console.log('promise 1') })注册一个微任务,放入微任务队列
  17. 检查微任务队列,取出一个微任务Promise.resolve().then(() => { console.log('promise 1') })执行then回调,输出promise 1
  18. 此时微任务队列清空,无UI渲染需求,开启下一轮事件循环,执行下一个宏任务。取出一个宏任务setTimeout(() => { console.log('setTimeout 2') Promise.resolve().then(() => { console.log('promise 2') }) })输出setTimeout 2
  19. Promise.resolve().then(() => { console.log('promise 2') })注册一个微任务,放入微任务队列
  20. 检查微任务队列,取出一个微任务Promise.resolve().then(() => { console.log('promise 2') })执行then回调,输出promise 2
  21. 此时微任务队列清空,宏任务队列也清空,所有任务执行完毕。

输出结果为

arduino 复制代码
1
7
promise 3
promise 5
promise 4
promise 6
setTimeout 1
promise 1
setTimeout 2
promise 2
相关推荐
耶啵奶膘31 分钟前
uniapp-是否删除
linux·前端·uni-app
王哈哈^_^2 小时前
【数据集】【YOLO】【目标检测】交通事故识别数据集 8939 张,YOLO道路事故目标检测实战训练教程!
前端·人工智能·深度学习·yolo·目标检测·计算机视觉·pyqt
cs_dn_Jie3 小时前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic3 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿3 小时前
webWorker基本用法
前端·javascript·vue.js
cy玩具4 小时前
点击评论详情,跳到评论页面,携带对象参数写法:
前端
qq_390161774 小时前
防抖函数--应用场景及示例
前端·javascript
John.liu_Test5 小时前
js下载excel示例demo
前端·javascript·excel
Yaml45 小时前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理
PleaSure乐事5 小时前
【React.js】AntDesignPro左侧菜单栏栏目名称不显示的解决方案
前端·javascript·react.js·前端框架·webstorm·antdesignpro