一、为什么js浏览器中有事件循环的机制?
1.因为js是单线程在代码执行时,通过将不同函数的执行上下文压入执行栈中来保证代码的有序执行。
2.在执行同步代码时,如果遇到异步事件,js 引擎并不会一直等待其返回结果,而是会将这个事件挂起,继续执行执行栈中的其他任务。当异步事件执行完毕后,再将异步事件对应的回调加入到一个任务队列中等待执行。
3.任务队列可以分为宏任务队列和微任务队列,当当前执行栈中的事件执行完毕后,js 引擎首先会判断微任务队列中是否有任务可以执行,如果有就将微任务队首的事件压入栈中执行。当微任务队列中的任务都执行完成后再去执行宏任务队列中的任务。
二、两种任务
宏任务:整体代码、setTimeout、setIntervel、I/O操作
微任务:new Promise().then、MutaionObserver(前端回溯)
三、为什么要引入微任务的概念,只有宏任务可以吗?
宏任务先进先出的原则执行,并不能很好的控制任务的位置。如果这个时候有一个优先级比较高的任务需要去执行怎么办呢?只能等待前面的宏任务执行完再轮到它。所以为解决这一问题引入了微任务。
测试题目
第一题
async function async1(){
console.log('async1 start')
await async2()
console.log('async1 end')
}
async function async2(){
console.log('async2')
}
console.log('script start')
setTimeout(function(){
console.log('setTimeout')
},0)
async1()
new Promise(function(resolve){
console.log('promise1')
resolve()
}).then(function(){
console.log('promise2')
})
console.log('script end')
输出结果:
第二题
console.log('start')
setTimeout(()=>{
console.log('children2')
Promise.resolve().then(()=>{
console.log('children3')
})
},0)
new Promise(function(resolve,reject){
console.log('children4')
setTimeout(function(){
console.log('children5')
resolve('children6')
},0)
}).then((res)=>{
console.log('children7')
setTimeout(()=>{
console.log(res)
},0)
})
输出结果
第三题
const p=function(){
return new Promise((resolve,reject)=>{
const p1=new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(1)
},0)
resolve(2)
})
p1.then((res)=>{
console.log(res)
})
console.log(3)
resolve(4)
})
}
p().then((res)=>{
console.log(res)
})
console.log('end')
输出结果
第四题
将resolve(2)去掉
输出结果