js事件循环实例解析

js执行顺序分析

console.log(1)

setTimeout(()=>{
    console.log(2)
},2000)

setTimeout(()=>{
    console.log(3)
    Promise.resolve().then(()=>{
        console.log(4)
    })
    setTimeout(()=>{
        console.log(5)
    },3000)
},1000)

new Promise((resolve,reject)=>{
    console.log(6)
    resolve()
}).then(()=>{
    console.log(7)
})

console.log(8)

// 输出结果:1,6,8,7,3,4,2,5

image

同步任务
  • js单线程,解释执行

异步任务

MacroTask(Task): 宏任务。
  • 整体代码的script、setTimeout、setInterval、setImmediate、requestAnimationFrame、I/O、UI rendering;
MicroTask:微任务。
  • process.nextTick(Node环境中),Promise,Object.observe(基本废弃)

解析:

第一步:执行同步任务,并挂起异步任务
  • js为单线程,解释性语言,因此从头至尾逐行执行,遇到异步任务挂起至异步线程
  • 因此 首先依次输出 1 6 8
  • 注意:Promise中.then和.catch属于微任务,本身的回调函数属于同步任务,在主线程中直接执行
第二步:执行异步任务队列中的第一个宏任务
  • 异步任务挂起至异步线程中
  • 异步任务执行结束,拿到结果之后,将在异步队列中注册回调函数
  • 异步队列中的任务,优先执行宏任务,遇到微任务挂起至微任务栈中,待当前宏任务执行完毕后,执行完微任务栈中的所有微任务,
  • 然后执行宏任务队列中的第二个宏任务,重复上一步
  • 因此 此过程依次输出: 7
第三步:关于setTimeout
  • 一次性定时器,因为有延时,因此放在宏任务的最后执行
  • 一秒延时的定时器早于两秒延时的定时器的执行
  • 因此 此过程输出 3 4
  • 一秒定时器内部的三秒定时器,总延时长长于两秒
  • 因此 优先执行两秒定时器结果,之后执行一秒定时器的子定时器(三秒定时器)
  • 此过程输出 2 5

注意:宏任务中js执行顺序,和同步任务中js执行原理一致
注意:promise 是在当前脚本代码执行完后,立刻执行的,它并没有参与事件循环,所以它的优先级是高于 setTimeout
宏任务本质:参与了事件循环的任务
微任务本质:直接在 Javascript 引擎中的执行的,没有参与事件循环的任务

猜你喜欢

转载自www.cnblogs.com/nanhuaqiushui/p/11787480.html