欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 维修 > Vue JS执行机制和nextTick

Vue JS执行机制和nextTick

2025/2/26 2:25:19 来源:https://blog.csdn.net/YUELEI118/article/details/141527290  浏览:    关键词: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(()=>{// 代码放在这里执行}),添加到微任务队列中执行

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词