/**
* Defer a task to execute it asynchronously.
*/var nextTick =(function(){// 闭包 内部变量var callbacks =[];// 执行队列var pending =false;// 标识,用以判断在某个事件循环中是否为第一次加入,第一次加入的时候才触发异步执行的队列挂载var timerFunc;// 以何种方法执行挂载异步执行队列,这里假设Promise是完全支持的functionnextTickHandler(){// 异步挂载的执行任务,触发时就已经正式准备开始执行异步任务了 pending =false;// 标识置falsevar copies = callbacks.slice(0);// 创建副本 callbacks.length =0;// 执行队列置空for(var i =0; i < copies.length; i++){ copies[i]();// 执行}}// 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 if */if(typeof Promise !=='undefined'&&isNative(Promise)){var p = Promise.resolve();varlogError=function(err){ console.error(err);};timerFunc=function(){ p.then(nextTickHandler).catch(logError);// 挂载异步任务队列// 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);}};}elseif(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 IE11, iOS7, Android 4.4var counter =1;var observer =newMutationObserver(nextTickHandler);var textNode = document.createTextNode(String(counter)); observer.observe(textNode,{characterData:true});timerFunc=function(){ counter =(counter +1)%2; textNode.data =String(counter);};}else{// fallback to setTimeout/* istanbul ignore next */timerFunc=function(){setTimeout(nextTickHandler,0);};}returnfunctionqueueNextTick(cb, ctx){// nextTick方法真正导出的方法var _resolve; callbacks.push(function(){// 添加到执行队列中 并加入异常处理if(cb){try{cb.call(ctx);}catch(e){handleError(e, ctx,'nextTick');}}elseif(_resolve){_resolve(ctx);}});//判断在当前事件循环中是否为第一次加入,若是第一次加入则置标识为true并执行timerFunc函数用以挂载执行队列到Promise// 这个标识在执行队列中的任务将要执行时便置为false并创建执行队列的副本去运行执行队列中的任务,参见nextTickHandler函数的实现// 在当前事件循环中置标识true并挂载,然后再次调用nextTick方法时只是将任务加入到执行队列中,直到挂载的异步任务触发,便置标识为false然后执行任务,再次调用nextTick方法时就是同样的执行方式然后不断如此往复if(!pending){ pending =true;timerFunc();}if(!cb &&typeof Promise !=='undefined'){returnnewPromise(function(resolve, reject){ _resolve = resolve;})}}})();