nextTick 解析

本文详细介绍了JavaScript的单线程执行机制、宏任务与微任务的概念,并通过代码示例解释了它们之间的执行顺序。同时,文章探讨了Vue框架中的nextTick机制,如何在DOM更新后执行回调,帮助开发者理解异步更新队列的工作原理。
摘要由CSDN通过智能技术生成
     nextTick 是 Vue 的一个核心实现,在开发过程中会遇到在声明周期中没有获取到及时更新的值或Dom,我们会使用nextTick,将nextTick(callBack)放到异步任务队列中
在下主线程任务执行完成后再去执行。

主要涉及以下知识点

1. JS 的运行机制。

2. 宏观任务 macro task

3. 微观任务 micro task

一:JS 的运行机制

javaScript是一门单线程语言,所以一切javascript版的”多线程”都是用单线程模拟出来的,一切javascript多线程都是纸老虎!
javaScript 是单线程的, 那么可以预见会有等待加载这种,如果网页初始化数据量很大,执行时间很长,那么对用户体验是十分不友好的,所以为了解决这种问题,出现了同步、异步任务

1. 同步和异步任务分别进入不同的执行”场所”,同步的进入主线程,异步的进入 Event Table并注册函数直接返回回调或等待完成时返回回调。

2. 当指定的事情完成时,Event Table会将这个函数移入Event Queue(遵循先进执行的原则)。

3. 主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。

4. 上述过程会不断重复,也就是常说的Event Loop(事件循环)。

        我们不禁要问了,那怎么知道主线程执行栈为空啊?js引擎存在monitoring process进程,会持续不断的检查主线程执行栈是否为空,一旦为空,就会去Event Queue那里检查是否有等待被调用的函数。
那么接下来看几行代码
setTimeout (function () {
    console.log(‘定时器开始啦’)
});
new Promise(function (resolve) {
    console.log(‘马上执行for循环啦’);
   for (var i = 0; i < 10000; i++) {
      i == 99 && resolve();
   } }).then(function () {
    console.log(‘执行then函数啦’)
});
console.log(‘代码执行结束’);
执行结果
1. 马上执行for循环啦
2. 代码执行结束
3. 执行then函数啦
4. 定时器开始啦

二:JS 循环执行机制

        大家不知道有没有疑问 1. 马上执行for循环啦 2. 代码执行结束 大家肯定不会有疑问
        因为单线程执行,重上往下。那么对于为什么 promise 在执行 setTimeout, 不是应该setTimeout 先进入Event Queue中的么? 这里就涉及js执行顺序、宏观、微观
       js的循环顺序、先执行宏观(包含主线程)执行完毕后、在执行微观任务、然后再次执行宏观,找到其中一个任务队列执行完毕,再执行所有的微任务

1. 宏观 script,setTimeout,setInterval,setImmediate, MessageChannel,postMessage

setImmediate
该方法用来把一些需要长时间运行的操作放在一个回调函数里,在浏览器完成后面的其他语句后,就立刻执行这个回调函数
var immediateID = setImmediate(func, [param1, param2, …]);
immediateID 是这次setImmediate方法设置的唯一ID,可以作 为 window.clearImmediate 的参数(取消执行).
func 是将要执行的回调函数
参数param1 param2 ..都会直接传给函数func
MessageChannel
是一个实例化构造函数接口允许我们创建一个新的消息通道,并通过它的两个属 性发送数据
const channel = new MessageChannel();
channel 有两个方法
channel.port2 channel.port2.postMessage(1)给 port1发送消息
channel.port1 channel.port1.onmessage 接收消息执行回调

2. 微观 Promise,process.nextTick,MutationObsever

我们再来看一段复杂的代码
主线程
console.log(’99’);
异步 宏观
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(’77’);
    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’)
    })
})
执行结果
第一轮事件循环
先走 主线程宏观 打印 99、 77
执行微观任务 6、8
第二轮事件循环
先走该任务的异步宏观 2、4
在执行该任务的微观任务 3 .5
第三轮事件循环
先走该任务的异步宏观 9、11
在执行该任务的微观任务10、12

Vue.nextTick(callBack)就是将callBack放到下次循环中执行

放到宏观还是微观中,Vue 根据各种场景有不同的区分

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值