最新从 Event Loop 角度解读 Vue NextTick 源码,做了6年的前端

紧跟潮流

大前端和全栈是以后前端的一个趋势,懂后端的前端,懂各端的前端更加具有竞争力,以后可以往这个方向靠拢。

这边整理了一个对标“阿里 50W”年薪企业高级前端工程师成长路线,由于图片太大仅展示一小部分

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

接下来我们来看整个文件。

  1. 声明了三个全局变量,callbacks: [] ,pending: Boolean,timerFunc: undefined

  2. 声明了一个函数 flushCallbacks

  3. 一堆 **if,else if **判断。

  4. 抛出了一个函数 nextTick

nextTick 函数

  1. 声明一个局部变量 _resolve 。

  2. 把所有回调函数压进 callbacks 中,以栈的形式的存储所有 callback

  3. 当 pending 为 false 时,执行 timerFunc 函数。

  4. 当没有 callback 的时候,返回一个 Promise 的调用方式,可以用 .then 接收。

timerFunc 函数

我们开始说了,timerFunc 为全局变量,现在调用 timerFunc ,timerFunc 是什么时候被赋值为一个函数,并且函数里执行代码又是什么?

我们看到,这段判断代码总共有四个分支,四个分支里对 timerFunc 有不同的赋值,我们先来看第一个分支。

Promise 分支

if (typeof Promise !== ‘undefined’ && isNative(Promise)) {

const p = Promise.resolve()

timerFunc = () => {

p.then(flushCallbacks)

// In problematic UIWebViews, Promise.then doesn’t completely break, but

// it can get stuck in a weird state where callbacks are pushed into the

// microtask queue but the queue isn’t being flushed, until the browser

// needs to do some other work, e.g. handle a timer. Therefore we can

// “force” the microtask queue to be flushed by adding an empty timer.

if (isIOS) setTimeout(noop)

}

isUsingMicroTask = true

}

复制代码

  1. 判断环境是否支持 Promise 并且 Promise 是否为原生。

  2. 使用 Promise 异步调用 flushCallbacks 函数。

  3. 当执行环境是 iPhone 等,使用 setTimeout 异步调用 noop ,iOS 中在一些异常的webview 中,promise 结束后任务队列并没有刷新所以强制执行 setTimeout 刷新任务队列。

MutationObserver 分支

else if (!isIE && typeof MutationObserver !== ‘undefined’ && (

isNative(MutationObserver) ||

// PhantomJS and iOS 7.x

MutationObserver.toString() === ‘[object MutationObserverConstructor]’

)) {

// Use MutationObserver where native Promise is not available,

// e.g. PhantomJS, iOS7, Android 4.4

// (#6466 MutationObserver is unreliable in IE11)

let counter = 1

const observer = new MutationObserver(flushCallbacks)

const textNode = document.createTextNode(String(counter))

observer.observe(textNode, {

characterData: true

})

timerFunc = () => {

counter = (counter + 1) % 2

textNode.data = String(counter)

}

isUsingMicroTask = true

}

复制代码

  1. 对非IE浏览器和是否可以使用 HTML5 新特性 MutationObserver 进行判断。

  2. 实例一个 MutationObserver 对象,这个对象主要是对浏览器 DOM 变化进行监听,当实例化 MutationObserver 对象并且执行对象 observe,设置 DOM 节点发生改变时自动触发回调。

  3. 把 timerFunc 赋值为一个改变 DOM 节点的方法,当 DOM 节点发生改变,触发 flushCallbacks 。(这里其实就是想用利用 MutationObserver 的特性进行异步操作)

setImmediate 分支

else if (typeof setImmediate !== ‘undefined’ && isNative(setImmediate)) {

// Fallback to setImmediate.

// Technically it leverages the (macro) task queue,

// but it is still a better choice than setTimeout.

timerFunc = () => {

setImmediate(flushCallbacks)

}

}

复制代码

  1. 判断 setImmediate 是否存在,setImmediate 是高版本 IE (IE10+) 和 edge 才支持的。

  2. 如果存在,传入 flushCallbacks 执行 setImmediate 。

setTimeout 分支

else {

// Fallback to setTimeout.

timerFunc = () => {

setTimeout(flushCallbacks, 0)

}

}

复制代码

最后

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
就答题情况而言,第一问100%都可以回答正确,第二问大概只有50%正确率,第三问能回答正确的就不多了,第四问再正确就非常非常少了。其实此题并没有太多刁钻匪夷所思的用法,都是一些可能会遇到的场景,而大多数人但凡有1年到2年的工作经验都应该完全正确才对。
只能说有一些人太急躁太轻视了,希望大家通过此文了解js一些特性。

并祝愿大家在新的一年找工作面试中胆大心细,发挥出最好的水平,找到一份理想的工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值