标签:利用 The call 复制 嗅探 immediate for back 使用
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
标签:利用 The call 复制 嗅探 immediate for back 使用
原文地址:https://www.cnblogs.com/musi03/p/12665892.html