码迷,mamicode.com
首页 > 其他好文 > 详细

vue知识

时间:2020-04-09 12:28:50      阅读:94      评论:0      收藏:0      [点我收藏+]

标签:利用   The   call   复制   嗅探   immediate   for   back   使用   

nextTick实现原理?

nextTick方法主要是使用了宏任务和微任务,定义一个异步方法,多次调用nextTick会将方法存在队列中,通过这个异步方法清空当前队列。所以这个nextTick方法就是异步方法

这句话说的很乱,典型的让面试官忍不住想要深挖一探究竟的回答。(因为一听你就不是真的懂)

正确的流程应该是先去 嗅探环境,依次去检测

Promise的then -> MutationObserver的回调函数 -> setImmediate -> setTimeout 是否存在,找到存在的就使用它,以此来确定回调函数队列是以哪个 api 来异步执行。

nextTick 函数接受到一个 callback 函数的时候,先不去调用它,而是把它 push 到一个全局的 queue 队列中,等待下一个任务队列的时候再一次性的把这个 queue 里的函数依次执行。

这个队列可能是 microTask 队列,也可能是 macroTask 队列,前两个 api 属于微任务队列,后两个 api 属于宏任务队列。

简化实现一个异步合并任务队列:

let pending = false
// 存放需要异步调用的任务
const callbacks = []
function flushCallbacks () {
  pending = false
  // 循环执行队列
  for (let i = 0; i < callbacks.length; i++) {
    callbacks[i]()
  }
  // 清空
  callbacks.length = 0
}

function nextTick(cb) {
    callbacks.push(cb)
    if (!pending) {
      pending = true
      // 利用Promise的then方法 在下一个微任务队列中把函数全部执行 
      // 在微任务开始之前 依然可以往callbacks里放入新的回调函数
      Promise.resolve().then(flushCallbacks)
    }
}
复制代码

测试一下:

// 第一次调用 then方法已经被调用了 但是 flushCallbacks 还没执行
nextTick(() => console.log(1))
// callbacks里push这个函数
nextTick(() => console.log(2))
// callbacks里push这个函数
nextTick(() => console.log(3))

// 同步函数优先执行
console.log(4)

// 此时调用栈清空了,浏览器开始检查微任务队列,发现了 flushCallbacks 方法,执行。
// 此时 callbacks 里的 3 个函数被依次执行。

// 4
// 1
// 2
// 3

vue知识

标签:利用   The   call   复制   嗅探   immediate   for   back   使用   

原文地址:https://www.cnblogs.com/musi03/p/12665892.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!