JS事件循环机制

前置知识

js是一门单线程语言, 单线程的意思是 js执行环境中负责执行代码的线程只有一个
js最早是一门运行在浏览器端的脚本语言, 目的是为了实现页面上的动态交互, 核心就是 DOM 操作, 这就决定了他必须使用单线程模式工作 (多线程的情况下, 我在一个线程修改dom, 另一个线程删除dom就会出现线程同步问题)

一个线程一次就只能执行一个问题, 多个问题需要处理的情况就需要排队, 安全简单, 但容易阻塞

js的异步模式:

  • 不会等待这个任务的结束才开始下一个任务
  • 对于耗时操作开启过后就立即往后执行下一个任务
  • 耗时任务的后续逻辑一般通过回调函数的方式定义, 耗时任务完成过后就会自动执行传入的回调

在这里插入图片描述

console.log('global begin')

setTimeout(function(timer1(){
	console.log('timer1 invoke')
},1800)

setTimeout(function timer2(){
	console.log('timer2 invoke')
	
	setTimeout(function inner(){
		console.log('inner invoke')
	},1000)
},1000)

console.log('global end')

setTimeout 是异步调用, 内部的API环境就是为回调函数开启了一个倒计时器,放到一边,这里的倒计时器是单独工作的, 并不会受js线程影响, 在web中对应线程开启, 计时结束后就将回调函数推入事件队列, 等待主执行栈空闲的时候读取调用, ajax, dom操作类似

宏任务 / 微任务
宏任务: script整体代码, setTimeout, setInterval…
微任务: promise & process.nextTick() & mutationobserver…

微任务就像是你在移动营业厅办理业务, 完事之后你突然想起来没得花费了,要冲一下, 这时候业务员也会马上给你办理, 不需要你重新去排队, 所以微任务会在当前主代码执行完毕之后立即执行
而宏任务会在当前主代码及与之相关的微任务执行完之后, 去读取任务队列执行, 在执行宏任务代码中产生的微任务又会在任务执行完后立即执行, 如此循环
在这里插入图片描述

Promise即便没有任何操作, 他的回调也是异步的

废话不说先上题吧

async function async1() {
  console.log('async1 start')
  await async2()
  console.log('async1 end')
}
async function async2() {
  console.log('async2 start')
  await async3()
  console.log('async2 end')
}
async function async3() {
  console.log('async3 start')
}

setTimeout(() => {
  console.log('setTimeout')
}, 0)

console.log('script start')
async1()
new Promise((resolve) => {
  console.log('promise1')
  setTimeout(resolve, 0)
}).then(() => {
  console.log('promise1 then')
})
new Promise((resolve) => {
  console.log('promise2')
  resolve()
}).then(() => {
  console.log('promise2 then')
})
console.log('script end')
  1. 代码从上往下执行, 遇到setTimeout放入宏任务队列
  2. 输出 script start
  3. 调用函数 async1, 输出 async1 start, 往下执行,
  4. 进入async2, 输出async2 start
  5. 进入 async3, 输出 async3 start
  6. async3 调用结束, 后续代码进入微任务队列
  7. 代码继续往下执行, 遇到 new Promise, 输出 promise1
  8. 遇到 setTimeout(resolve,0), 这行代码是将 promise 的完成放在了一个0秒的计时器中, 该代码被放入宏任务队列排队
  9. 继续往下执行, 输出promise2, resolve() 改变了promise的状态, then方法回调推入微任务对列
  10. 继续往下执行, 输出 script end
  11. 主线程执行完毕, 读取微任务继续执行
  12. 首先输出 async2 end, 此时 async1中 async2的调用结束, 后续代码推入微任务队列, 继续执行当前微任务队列的下一个微任务
  13. 输出 promise2 then, 继续微任务队列
  14. 输出async1 end, 当前微任务队列执行完毕为空, 执行下一个宏任务
  15. 执行第一个setTimeout, 输出setTimeout
  16. 当前微任务队列为空, 执行下一个宏任务
  17. 执行setTimeout(resolve, 0), 结束当前promise, 后续回调进入微任务队列
  18. 读取微任务队列任务, 输出promise1 then
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值