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");
})

// 微任务队列中的任务,2
  await 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 || resolvedPromise
  return fn ? p.then(this ? fn.bind(this) : fn) : p
}
  • 为什么加上nextTick就可以刷新Dom?
    源码分析可知,使用nextTick后,代码会放入到Promise.resolve().then(()=>{// 代码放在这里执行}),添加到微任务队列中执行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值