事件循环分为主线程(同步任务)和异步队列(异步任务,先微任务后宏任务)
异步:
(微任务 程序行为)promise、.then.catch.finally、nodejs、nextTick
(宏任务 浏览器机制)setTimeout、setInterval、AJAX
宏任务 - 微任务 :事件循环
先执行当下的微任务的所有任务,再执行宏任务队列里面的所有任务\
console.log(1)//同步
setTimeout(()=>{
console.log(2)//宏任务
},0)
new Promise((resolve)=>{
resolve()
console.log(3)//同步
}).then(()=>{
console.log(4)//微任务
}).finally(()=>{
console.log(5)//微任务
})
console.log(6)//同步
//1、3、6、4、5、2
async-await
es7,前端推出异步编程的终极解决方案(用同步的方式去写异步),await后面一般跟一个Promise,永远会等到后面的promise进行resolve,如果reject就会抛出错误,要用try-catch来捕获错误,async在await之前都是同步任务
test(){
console.log(2)//同步
await new Promise()
console.log(3)//await后面是异步,微任务
}
test1(){
console.log(1)//同步
this.test()
console.log(4)//同步
//输出的结果是1、2、4、3
}
test1()
以前是微任务和宏任务,不满足需求,现在是队列更加灵活
分为微队列(最高)、用户队列(高)、延时队列,w3c每个任务有不同的类型,同类型属于一个任务队列,在一次时间循环中,有浏览器决定哪一个任务队列,但浏览器必须有一个微队列,是最高优先级,必须优先执行
promise的then是将任务放到微队列
事件循环又叫消息循环,是浏览器渲染主线程的工作方式,在chrome的源码里开启一个不会结束的for循环,每次循环从消息队列里面拿出第一个任务执行,其他线程只需要在合适的时间里加到队列的末尾即可
2.js的计时器不能做到精准计时 a.计算机硬件没有原子钟 b.操作系统本身就有偏差,js函数还是属于操作系统的函数 c.w3c的标准,如果嵌套超过五层就会有最少4毫秒的偏差 d.受事件循环影响,计时器的回调函数只有在主线程空闲时运行,才不会有偏差