Vue中之nextTick函数源码分析详解(2)
整体思路理解:首先 nextTick 是一个闭包函数,代码立即执行,在理解整体代码之前,我们先来看个类似的demo,如下代码:
<!DOCTYPE html> <html> <head> <title>演示Vue</title> </head> <body> <div id="app"> </div> <script> var nextTick = (function(){ return function queueNextTick(cb, ctx) { if (cb) { try { cb.call(ctx) } catch (e) { console.log('出错了'); } } } })(); // 方法调用 nextTick(function(){ console.log(2); // 打印2 }) </script> </body> </html>
demo代码和上面的代码很类似。
我们也可以再来抽离使用nextTick做demo代码如下:
var nextTick2 = (function(){ const callbacks = []; let pending = false; let timerFunc; function nextTickHandler () { pending = false const copies = callbacks.slice(0) callbacks.length = 0 for (let i = 0; i < copies.length; i++) { copies[i]() } } if (typeof Promise !== 'undefined') { var p = Promise.resolve() var logError = err => { console.error(err) } timerFunc = () => { p.then(nextTickHandler).catch(logError) } } else if (typeof MutationObserver !== 'undefined' || // PhantomJS and iOS 7.x MutationObserver.toString() === '[object MutationObserverConstructor]' ) { // use MutationObserver where native Promise is not available, // e.g. PhantomJS IE11, iOS7, Android 4.4 var counter = 1 var observer = new MutationObserver(nextTickHandler) var textNode = document.createTextNode(String(counter)) observer.observe(textNode, { characterData: true }) timerFunc = () => { counter = (counter + 1) % 2 textNode.data = String(counter) } } else { // fallback to setTimeout /* istanbul ignore next */ timerFunc = () => { setTimeout(nextTickHandler, 0) } } return function queueNextTick (cb, ctx) { let _resolve callbacks.push(() => { if (cb) { try { cb.call(ctx) } catch (e) { handleError(e, ctx, 'nextTick') } } else if (_resolve) { _resolve(ctx) } }) if (!pending) { pending = true timerFunc() } if (!cb && typeof Promise !== 'undefined') { return new Promise((resolve, reject) => { _resolve = resolve }) } } })(); nextTick2(function(){ console.log(2222); });
如上代码是nextTick源码的抽离,为了更好的理解nextTick,做了如上的demo。
我们再来理解一下整体的代码的含义;
先定义数组 callbacks = [];来存放所有需要执行的回调函数,定义let pending = false;判断本轮事件是否执行过 timerFunc(nextTickHandler, 0)这个函数,为true说明执行过 timeFunc函数,接着定义nextTickHandler函数,该函数的作用是依次遍历数组callbacks保存的函数,依次执行;
请看源代码如下:
function nextTickHandler () { pending = false const copies = callbacks.slice(0) callbacks.length = 0 for (let i = 0; i < copies.length; i++) { copies[i]() } }
内容版权声明:除非注明,否则皆为本站原创文章。