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

vue.$nextTick实现原理

时间:2020-11-02 10:20:23      阅读:24      评论:0      收藏:0      [点我收藏+]

标签:snat   fine   catch   res   ++   string   ring   def   cti   

源码:

		const callbacks = []
		let pending = false

		function flushCallbacks () {
		  pending = false
		  const copies = callbacks.slice(0)
		  callbacks.length = 0
		  for (let i = 0; i < copies.length; i++) {
		    copies[i]()
		  }
		}
		let timerFunc
		if (typeof Promise !== ‘undefined‘ && isNative(Promise)) {
		  const p = Promise.resolve()
		  timerFunc = () => {
		    p.then(flushCallbacks)
		    if (isIOS) setTimeout(noop)
		  }
		  isUsingMicroTask = true
		} else if (!isIE && typeof MutationObserver !== ‘undefined‘ && (
		  isNative(MutationObserver) ||
		  MutationObserver.toString() === ‘[object MutationObserverConstructor]‘
		)) {
		  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
		} else if (typeof setImmediate !== ‘undefined‘ && isNative(setImmediate)) {
		  timerFunc = () => {
		    setImmediate(flushCallbacks)
		  }
		} else {
		  timerFunc = () => {
		    setTimeout(flushCallbacks, 0)
		  }
		}

		export function nextTick (cb?: Function, ctx?: Object) {
		  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 => {
		      _resolve = resolve
		    })
		  }
		}

  总体来说:就是先判断是否支持promise,如果支持promise。就通过Promise.resolve的方法,异步执行方法,如果不支持promise,就判断是否支持MutationObserver。如果支持,就通过MutationObserver(微异步)来异步执行方法,如果MutationObserver还不支持,就通过setTimeout来异步执行方法。

  MutaionObserver通过创建新的节点,调用timerFunc方法,改变MutationObserver监听的节点变化,从而触发异步方法执行。

vue.$nextTick实现原理

标签:snat   fine   catch   res   ++   string   ring   def   cti   

原文地址:https://www.cnblogs.com/yaxinwang/p/13827530.html

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