// 修改数据vm.msg ='Hello';// DOM 还没有更新Vue.nextTick(function() {// DOM 更新了});// 作为一个 Promise 使用Vue.nextTick().then(function() {// DOM 更新了});
能力检测
按照优先级检测
native promise
MutationObserver(非ie)
setImmediate
setTimeout
官方文档注释中,MutationObserver有更广的适配,但是ie11和UIWebView in iOS >= 9.3.3有严重的bug,所以native promise是第一优先级的
// The nextTick behavior leverages the microtask queue, which can be accessed// via either native Promise.then or MutationObserver.// MutationObserver has wider support, however it is seriously bugged in// UIWebView in iOS >= 9.3.3 when triggered in touch event handlers. It// completely stops working after triggering a few times... so, if native// Promise is available, we will use it:/* istanbul ignore next, $flow-disable-line */if (typeofPromise!=='undefined'&&isNative(Promise)) {constp=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} elseif (!isIE &&typeof MutationObserver !=='undefined'&& (isNative(MutationObserver) ||// PhantomJS and iOS 7.xMutationObserver.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 =1constobserver=newMutationObserver(flushCallbacks)consttextNode=document.createTextNode(String(counter))observer.observe(textNode, { characterData:true })timerFunc= () => { counter = (counter +1) %2textNode.data =String(counter) } isUsingMicroTask =true} elseif (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) }} else {// Fallback to setTimeout.timerFunc= () => {setTimeout(flushCallbacks,0) }}