在vue项目中,经常会使用到nextTick这个api,一直在猜想其是怎么实现的,今天有幸研读了下,虽然源码又些许问题,但仍值得借鉴 判断是否支持promise,如果支持就使用Promise对象的then方法包裹要执行的 flushCallbacks函数 判断是否支持MutationObserver,如果支持就创建一个MutationObserver 用于监听dom改动之后执行 flushCallbacks 函数 并赋值给 observer 判断是否支持setImmediate,如果支持就使用setImmediate包裹 flushCallbacks函数 如果以上三种都不支持使用setImmediate包裹 flushCallbacks函数 export  let  isUsingMicroTask =  false 
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 ) 
  } 
} 
nextTick(cb?: Function, ctx?: Object) {
}
cb是 传入的回调函数 ctx是函数执行的上下文 而者都又是可选参数, 但是有问题 下文有解析 将调用nextTick是传入的执行函数添加到 callbacks中 可使用call和传入的ctx修改传入的执行函数的this指向 export  function  nextTick ( cb? :  Function,  ctx? :  Object )  { 
  
  
  
  let  _resolve
  
  callbacks. push ( ( )  =>  { 
    if  ( cb)  { 
      try  { 
        cb . call ( ctx) 
      }  catch  ( e)  { 
        
        handleError ( e,  ctx,  'nextTick' ) 
      } 
    }   
  } ) 
  
  if  ( ! pending)  { 
    
    pending =  true 
    timerFunc ( ) 
  } 
} 
这个代码有删减,因为其余代码不会执行是 伪代码 下文有解析 
 
nexttick的参数中cb不能为可选参数,如果cb参数不传将没有回调函数,nextTick将没有意义,并且ctx将成为第一个参数,由于是形参,ctx将顶替cb但是ctx不是函数类型,就会抛错 function  flushCallbacks ( )  { 
  
  pending =  false 
  const  copies =  callbacks. slice ( 0 ) 
  callbacks. length =  0 
  for  ( let  i =  0 ;  i <  copies. length;  i++ )  { 
    
    copies[ i] ( ) 
  } 
} 
import  {  noop }  from  'shared/util' 
import  {  handleError }  from  './error' 
import  {  isIE,  isIOS,  isNative }  from  './env' 
export  let  isUsingMicroTask =  false 
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)  { 
      
      console. log ( 'ctx' ) 
      _resolve ( ctx) 
    } 
  } ) 
  
  if  ( ! pending)  { 
    
    pending =  true 
    timerFunc ( ) 
  } 
  
  if  ( ! cb &&  typeof  Promise !==  'undefined' )  { 
    
    
    return  new  Promise ( resolve  =>  { 
      _resolve =  resolve
    } ) 
  } 
} 
本人实在是不太理解下列代码的意义是什么,感觉是没用的,但是不太确定,以下是个人分析 首先将执行上下文this抛出是没什么意义的 其次promise的resolve 单独拿出来在此处有什么作用呢  let  _resolve
  if  ( ! cb &&  typeof  Promise !==  'undefined' )  { 
    
    
    return  new  Promise ( resolve  =>  { 
      _resolve =  resolve
    } ) 
  } 
        _resolve ( ctx) 
感谢您百忙之中抽时间阅读我写的博客,谢谢你的肯定,也希望对您能有所帮助 如果您有更好的见解请在评论区留言或者私聊我,期待与您的交流