js的执行机制--EventLoop
单线程任务
同步任务
进入主线程
,异步任务
进入Event Table
并注册函数
- 当指定事件完成时,
Event Table
会将这个函数移入Event Queue
- 主线程内的任务执行完毕为空,会去
Event Queue
读取对应的函数进入主线程执行
- 重复上述过程,即Event Loop(事件循环)
怎么知道主线程执行栈为空?
异步任务
- 事件循环的顺序,决定js代码的执行顺序
- 进入整体代码(宏任务)后,开始第一次循环
- 接着执行所有的
微任务
- 再次执行
宏任务
,找到其中一个任务队列执行完毕
- 再执行所有
微任务
2.1 宏任务macro-task
- 整体代码script(UIrender)
- setTimeout
- setInterval
- setImmediate
- i/o
setTimeout
setTimeout(() => {
task()
console.log('延时3s')
}, 3000)
定义延时3s,实际却5、6s才执行函数,是怎么回事?
task()
进入Event Table
并注册,计时开始
- 执行
sleep函数
,计时仍在继续
- 3s到了,计时事件
timeout
完成,task()
进入Event Queue
,但是sleep
还没执行完,事件等待
sleep
执行完,task()
从Event Queue
进入主线程
执行
零延迟
-
零延迟(Zero delay)
并不意味着立即执行
- 在零延迟调用
setTimeout
时,并不是过了给定时间间隔就马上执行回调函数
- 其等待的时间基于队列正在等待的消息数量
总结
setTimeout(fn, 0)
的含义是: 指定任务在主线程最早可得的空闲时间执行。也就是说,尽可能早的执行。它在任务队列的尾部添加一个事件,因此要等到主线程把同步任务和任务队列现有的事件都处理完,才会得到执行
- 在某种程度上,我们可以利用
setTimeout(fn,0)
的特性,修正浏览器的任务顺序
setInterval
- 对于执行顺序来说,
setInterval
会隔指定的时间将注册的函数置入Event Queue
,如果前面的任务耗时太久,那么同样需要等待
2.2 微任务micro-task
- Promise
- process.nextTick
- mutationObserver
nextTick
nextTick的由来
- 由于vue的
数据驱动视图更新
是异步的,即修改数据的当下,视图不会立刻更新,而是等同一事件循环中的所有数据变化完成之后,再统一进行视图更新。
nextTick的触发时机
- 在同一事件循环中的数据变化后,DOM完成更新,立即执行
nextTick(callback)
内的回调。
应用场景
简单总结事件循环
- 同步代码执行 -> 查找异步队列,推入执行栈,执行
callback1[事件循环1]
->查找异步队列,推入执行栈,执行callback2[事件循环2]
...
- 即 每个异步callback,最终都会形成自己独立的一个事件循环。
结合nextTick的由来,可以推出每个事件循环中,nextTick触发的时机
- 同一事件循环中的代码执行完毕 -> DOM 更新 -> nextTick callback触发
总结
- 宏队列:执行每个宏队列时会先清空微任务队列
- 微队列:微队列为空时执行宏队列
栗子
console.log('1');
setTimeout(function() {
console.log('2');
process.nextTick(function() {
console.log('3');
})
new Promise(function(resolve) {
console.log('4');
resolve();
}).then(function() {
console.log('5')
})
})
process.nextTick(function() {
console.log('6');
})
new Promise(function(resolve) {
console.log('7');
resolve();
}).then(function() {
console.log('8')
})
setTimeout(function() {
console.log('9');
process.nextTick(function() {
console.log('10');
})
new Promise(function(resolve) {
console.log('11');
resolve();
}).then(function() {
console.log('12')
})
})
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
- 找不到素材资源介绍文章里的示例图片?
- 对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
- 模板不会安装或需要功能定制以及二次开发?
- 请QQ联系我们
发表评论
还没有评论,快来抢沙发吧!