宏任务与微任务,事件队列
了解:1. js事件轮询机制;2.js属于单线程(主线程);
js代码都是在主线程执行的,不过需要区分是同步执行还是异步执行。当代码为异步时,
它对应的就应该有回调函数。不同的任务对应于不同的回调,如"setTimeout"回调、"Ajax"请求的回调。
以及对应事件回调,如"点击事件"。
不同的回调函数会交给不同的模块管理,比如<<定时器模块、网络请求模块、事件处理模块>>。
那么,我们的回调什么时候执行呢?这个要取决于我们的回调函数什么时候放入我们的事件队列(EQ)里面。
单放入事件队列还不够,Js引擎会通过轮询方式去询问事件队列有回调函数吗?如果有就会将这个函数勾出去,
这也是大家为什么说回调函数为钩子函数原因。
宏任务:(异步任务)
分类:setTimeout,setInterval,requrestAnimationFrame(提前告知浏览器在下一次动画之前帮我们调用回调函数)
1.宏任务所处的队列就是宏任务队列。
2.第一个宏任务队列中只有一个任务:执行主线程的js代码。
2.宏任务队列可以有多个。
微任务:
分类:new Promise().then(回调1,回调2),process.nextTick
1.微任务所处的队列就是微任务队列
2.只有一个微任务队列。
3.在上一个宏任务执行完毕后,如果有微任务队列就会执行微任务队列中的所有任务。
看下面代码执行顺序是什么
console.log('--------------Start-----------------')
setTimeout(()=>{
console.log('setTime')
},0);
new Promise((resolve,reject) =>{
for(var i = 0; i < 5; i++){
console.log(i)
}
resolve() //修改promise状态为成功
}).then(()=>{
console.log('promise实例成功回调执行')
})
console.log('--------------End-----------------')
最后结果:
1. 首先打印—start—>
2. 紧接着往下是一个延时器回调,虽然时间为0s,但是定时器对应的是一个回调,不是立即执行。
延时器属于一个宏任务,最后会被放进宏任务队列中。
3. 同步执行new Promise,new的同时会执行内部for循环 并打印结果。
4. 调用reolve()方法。。
5. 一旦resolve被调用,状态会修改,会立马执行then()方法里面的resolve对应的回调。
上面说了,Promise.then(回调)属于微任务。会立即放入微任务队列
6. 放入微任务后会立即执行主线程代码—End—>因为它的优先级是最高的