当前位置: 首页 > news >正文

Vue JS执行机制和nextTick

参考文章:
JS执行机制详解
这一次,彻底弄懂 JavaScript 执行机制
在这里插入图片描述

  • 宏任务中的同步任务:script、new promise 立即执行
  • 宏任务(macro-task):setTimeOut、setInterval
  • 微任务(mincro-task):promise.then、process.nextTick(node)

setTimeOut:设置的时间意思是在多久后将此宏任务放到队列中,而不是在队列中等待时间到了才执行

await:微任务,在await之后执行的代码,必须等到await执行完毕后才可以执行,

执行流程

  1. 自上而下分析script中代码
  2. 同步任务依次加入主线程准备执行
  3. 宏任务放到宏任务队列中,微任务放到微任务队列
  4. 主线程中的代码执行,执行中出现的宏任务和微任务继续添加到队列中
  5. 微任务队列中任务放到主线程执行
  6. 微任务执行完毕(此时完成一个循环,开启下一个循环)
  7. 再把宏任务队列中任务放到主线程中执行,执行中出现的宏任务和微任务继续添加到队列中,重复步骤:4–7

示例代码

async function Prom() {console.log("1");await Promise.resolve();console.log("2");// 写在await Promise后面相当于then,加入微任务
}setTimeout(() => {console.log("3");Promise.resolve().then(() => {console.log(`4`);})
},0);Promise.resolve().then(() => {console.log("5");
})Prom();
console.log(0);

执行顺序

1. 自上而下分析script代码,进入主线程执行的是:
Prom();
console.log(0);
  1. 进入宏任务队列的代码:
setTimeout(() => {console.log("3");Promise.resolve().then(() => {console.log(`4`);})
},0);// 设置等待时间为0,立即会被放到宏任务队列中
  1. 进入微任务队列的代码:
Promise.resolve().then(() => {console.log("5");
})
  1. script中的代码都进入了相对应的队列,现在主线程开始执行
  2. 执行Prom();这个方法调用的Prom方法,代码是:
async function Prom() {console.log("1");await Promise.resolve();console.log("2");
}
  1. 执行console.log("Y");—控制器输出:1
  2. 执行下一句: await Promise.resolve();发现这是一个微任务,加入到微任务的队列中,现在微任务的队列中有两个任务:
// 微任务队列中的任务,1
Promise.resolve().then(() => {console.log("5");
})// 微任务队列中的任务,2await Promise.resolve();console.log("2");// 写在await Promise后面相当于then,加入微任务
  1. 主线程中还剩一个任务:console.log(0);,执行,控制器输出:1 0

  2. 此时主线程中的任务已经全部完成,接下来执行微任务队列

  3. 微任务中的任务放到主线程执行,微任务1:Promise.resolve().then(() => { console.log("5"); })控制器输出:1 0 5

  4. 微任务2:await Promise.resolve();console.log("2");控制器输出:1 0 5 2

  5. 此时微任务队列也被清空

  6. 此时一个循环周期的任务完成,准备执行下一个循环

  7. 宏任务队列的代码放入主线程执行

  8. 宏任务执行setTimeout()方法,console.log("3");控制器输出:1 0 5 2 3

  9. seiTimeout()方法中执行到 Promise.resolve().then(() => { console.log(4); })将此任务放入到微任务队列中,继续执行宏任务队列,宏任务队列此时已经没有任务。

  10. 执行微任务代码 Promise.resolve().then(() => { console.log(4); }),控制器输出:1 0 5 2 3 4

  11. 执行完毕,共用了两个执行周期

nextTick

  • 在组件中数据是同步的,Dom是异步的,当数据发生变化,Dom没有发生相应的变化,需要使用nextTick

有两种方法更新Dom

第一种

nextTick(()=>{// Todo:改变Dom的操作
})

第二种

  • 使用await,await后面的代码就是异步的微任务
async()=>{
}
await nexttick() 
// Todo:改变Dom的操作

nextTick源代码

export function nextTick<T = void, R = void>(this: T,fn?: (this: T) => R,
): Promise<Awaited<R>> {const p = currentFlushPromise || resolvedPromisereturn fn ? p.then(this ? fn.bind(this) : fn) : p
}
  • 为什么加上nextTick就可以刷新Dom?
    源码分析可知,使用nextTick后,代码会放入到Promise.resolve().then(()=>{// 代码放在这里执行}),添加到微任务队列中执行

http://www.mrgr.cn/news/9719.html

相关文章:

  • Matlab矩阵基础操作
  • 设计模式-visit模式-在语法树的实践
  • 手写SpringAOP
  • 【MySQL】MySQL表的增删改查(初阶)
  • Error connecting to node kafka9092 (id 1001 rack null)
  • react面试题七
  • 这个深度清理工具 真正做到释放电脑垃圾 秒删90%的C盘垃圾
  • ZooKeeper--基于Kubernetes部署ZooKeeper
  • 吴恩达机器学习课后作业-03多分类、神经网络前向传播
  • 一文了解内网穿透以及内网穿透工具 Sunny-Ngrok 的使用指南
  • Git 十大提示和技巧
  • 谷粒商城实战笔记-243-商城业务-购物车-RedirectAttribute-解决重复提交
  • 来自Meta的Transfusion:自回归与扩散的“融合”
  • Centos7整合fail2ban配置ssh和pgsql以及vault
  • 批量整理文件夹的得力助手:让杂乱无章变得井井有条
  • MFC工控项目实例之七点击下拉菜单弹出对话框
  • PHP多商户跨店统一消费券系统程序源码
  • 【图论】Tarjan算法(强连通分量)
  • 文件包含漏洞案例
  • 【C++】01背包问题暴力,记忆,动态规划解法