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
同步任务
- 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 引擎中的执行的,没有参与事件循环的任务
原文地址:https://www.cnblogs.com/nanhuaqiushui/p/11787480.html
时间: 2024-10-09 04:20:15