jQuery的回调对象Callbacks分析
Callbacks在jQuery中的地位是Deferred的基础,当然,也对外公开其方法。
Callbacks对象是统一管理多个函数的利器。其核心是参数options中的几个状态码的任意组合,非常灵活。
先来看看options
once: 只触发一次回调
memory: 如果是触发后状态,add后立即触发
unique: 添加相同回到函数,只触发其中一个
stopOnFalse: 回调中遇到return false, 后面都不执行。
首先是:
list = []
我们的工作就是在维护这个list
add: function() { if ( list ) { // First, we save the current length var start = list.length; (function add( args ) { jQuery.each( args, function( _, arg ) { var type = jQuery.type( arg ); if ( type === "function" ) { if ( !options.unique || !self.has( arg ) ) { list.push( arg ); } } else if ( arg && arg.length && type !== "string" ) { // Inspect recursively add( arg ); } }); })( arguments ); // Do we need to add the callbacks to the // current firing batch? if ( firing ) { firingLength = list.length; // With memory, if we're not firing then // we should call right away } else if ( memory ) { firingStart = start; fire( memory ); } } return this; },
其核心就是那个push方法。代码为什么这么多? 支持数组方式参数,遇到参数中有memory情况,执行方法。
remove方法:
remove: function() { if ( list ) { jQuery.each( arguments, function( _, arg ) { var index; while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { list.splice( index, 1 ); // Handle firing indexes if ( firing ) { if ( index <= firingLength ) { firingLength--; } if ( index <= firingIndex ) { firingIndex--; } } } }); } return this; },
其核心也是那个splice方法。
针对这个firing,后面介绍。
fire方法:
fire = function( data ) { memory = options.memory && data; fired = true; firingIndex = firingStart || 0; firingStart = 0; firingLength = list.length; firing = true; for ( ; list && firingIndex < firingLength; firingIndex++ ) { if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { memory = false; // To prevent further calls using add break; } } firing = false; if ( list ) { if ( stack ) { if ( stack.length ) { fire( stack.shift() ); } } else if ( memory ) { list = []; } else { self.disable(); } } }
其核心是哪个循环,拿出来一个个执行。
在这里有个stack
stack = !options.once && []
这是一个数组,干嘛用的呢?这是针对有些函数是延时函数,这种情况fire可能会延时,要先把它放到stack函数中。
这样,以上的firing状态也就可以理解了。
这就是Callbacks整体,其核心原理还算是比较简单了。