1 const callbacks = [] // 回调队列 2 let pending = false // 异步锁 3 function flushCallbacks () { 4 pending = false // 开锁 5 const copies = callbacks.slice(0) // 复制一份回调数组 6 callbacks.length = 0 // 清空原callback数组 7 for (let i = 0; i < copies.length; i++) { 8 copies[i]() 9 } 10 } 11 nextTick (cb?: Function, ctx?: Object) { 12 let _resolve 13 callbacks.push(() => { // callback数组添加回调函数 14 if (cb) { 15 try { 16 cb.call(ctx) 17 } catch (e) { 18 handleError(e, ctx, 'nextTick') 19 } 20 } else if (_resolve) { 21 _resolve(ctx) 22 } 23 }) 24 if (!pending) { // 判断是否需要添加任务队列 25 pending = true // 关锁 26 timerFunc() // timeFunc为兼容浏览器的任务队列方法法promise,setTiemout等,回调执行flushCallbacks 27 } 28 // $flow-disable-line 29 if (!cb && typeof Promise !== 'undefined') { 30 return new Promise(resolve => { 31 _resolve = resolve 32 }) 33 } 34 }next为什么定义pending锁 添加一个回调函数就关闭锁,此时处于执行完同步代码就执行异步代码的情况,这个变量作用是只开启一个异步任务,仍然可以继续添加回调函数,限制不开启多个异步更新队列
next为什么复制一份callback数组,回调函数队列
防止nextTick套用nextTick的情况,如果不做特殊处理会出现nextTick里面的nextTick提前进入任务队列, 相当于下一个班车的乘客提前上了上一个班车(例子生动形象) 实现简易版的nexttick1 let pendding = false; 2 let callback = [] 3 function flushCallback() { 4 let copies = callback.slice(0) // 复制一份callback 5 callback.length = 0 // 清空callback 6 for(var i = 0; i < copies.length; i++) { 7 copies[i]() 8 } 9 } 10 function nextTick(cb) { 11 callback.push(cb) 12 if (!pendding) { // 判断锁是否开着 13 pendding = true; // 关锁 14 setTimeout(flushCallback, 0) // 添加一个异步任务 15 } 16 }