jQuery callback源码分析
来源:互联网 发布:小夕kitty淘宝 编辑:程序博客网 时间:2024/06/07 05:50
self下的add()函数:
add: function() {if ( list ) {//当list为undefined时,不执行该if语句// First, we save the current lengthvar start = list.length;(function add( args ) {//此处args指对象argumentsjQuery.each( args, function( _, arg ) {var type = jQuery.type( arg );if ( type === "function" ) {//处理callbacks.add(函数A,函数B)的情况if ( !options.unique || !self.has( arg ) ) {list.push( arg );}} else if ( arg && arg.length && type !== "string" ) {//处理callbacks.add([函数A,函数B])的情况// Inspect recursivelyadd( arg );}});})( arguments );//对象arguments存放着add()函数中的参数// Do we need to add the callbacks to the// current firing batch?if ( firing ) {//如果在回调的函数中执行add,不管是不是$.Callbacks('memory'),都会执行添加的函数,例1firingLength = list.length;// With memory, if we're not firing then// we should call right away} else if ( memory ) {//如果不是在回调函数中执行add,并且$.Callbacks('memory'),则执行添加函数,例2//memory = options.memory && data; var callbacks = $.Callbacks('memory');则memory=datafiringStart = start;//start = list.length;fire( memory );}}return this;},
例1:如果在回调的函数中执行add,不管是不是$.Callbacks('memory'),都会执行添加的函数
var callbacks = $.Callbacks(); function aaa(){ alert(1); callbacks.add(bbb); } function bbb(){ alert(2) } callbacks.add(aaa); callbacks.fire();//会分别弹出1和2
var callbacks = $.Callbacks('memory'); function aaa(){ alert(1); } function bbb(){ alert(2); } callbacks.add(aaa); callbacks.fire(); callbacks.add(bbb);
例3:callbacks.fire()中可以添加参数,参数将传递给回调函数,如callbacks.fire(123);
var callbacks = $.Callbacks(); function aaa(n){ alert(n); } callbacks.add(aaa); callbacks.fire(123);//弹出123
self下的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 indexesif ( firing ) {//在回调的过程中remove,即回调函数中有callbacks.remove(函数名),例4if ( index <= firingLength ) {firingLength--;//firingLength = list.length;}if ( index <= firingIndex ) {//如果删除的函数,在次函数之前,例5firingIndex--;//firingIndex表示正在执行的函数在list中的下标}}}});}return this;},
var callbacks = $.Callbacks(); function a(){ console.log(1); } function b(){ console.log(2); callbacks.remove(c) } function c(){ console.log(3); } callbacks.add(a,b,c); callbacks.fire();//1 2 执行函数b()后,已经把函数c()删除了
例5:在回调的过程中remove,并且删除的函数,在次函数之前
var callbacks = $.Callbacks(); function a(){ console.log(1); } function b(){ console.log(2); callbacks.remove(a) } function c(){ console.log(3); } callbacks.add(a,b,c); callbacks.fire();//1 2 3 callbacks.fire();//2 3
self下的lock():
lock: function() {stack = undefined;if ( !memory ) {//当还没有执行过私有方法fire()时,memory的值时undefined。例7self.disable();}return this;},例6:执行过私有函数fire()后,fired=true,再执行callbacks.lock()后,只是不能调用不能通过fireWith()调用私有函数fire(),因为if ( list && ( !fired || stack ) )相当于if(false),但是还可以通过add()函数中调用私有函数fire(),调用的前提:
var callbacks = $.Callbacks('memory');并且在add()之前执行过私有函数fire(),
因为私有函数fire()未执行时,变量memory时undefined,执行过fire()后,memory = options.memory && data;即options.memory必须为true,add()才会调用私有函数fire()
var callbacks = $.Callbacks('memory'); function a(){ console.log(1); } function b(){ console.log(2); } function c(){ console.log(3); } callbacks.add(a); callbacks.fire();//1 callbacks.lock(); callbacks.add(b);//2 callbacks.add(c);//3 callbacks.fire();
例7:当还没有执行过私有方法fire()时,变量memory为undefined,此时执行执行callbacks.lock(),就是执行
self.disable()
disable: function() {list = stack = memory = undefined;return this;},执行disable()后,fireWith()中的if ( list && ( !fired || stack ) )相当于if(false),虽然( !fired || stack )为true,但是list=undefined,也不能执行add()操作,因为list=undefined,不能执行list.push( arg ),
var callbacks = $.Callbacks('memory'); function a(){ console.log(1); } callbacks.lock(); callbacks.add(a);//没有结果 callbacks.fire();//没有结果
lock()和disable()的区别:
调用私有函数fire()有两种渠道:
通过fireWith()调用私有函数fire(),只要if ( list && ( !fired || stack ) )为真;
通过add()函数中调用私有函数fire(),调用的前提:var callbacks = $.Callbacks('memory');并且在add()之前执行过私有函数fire(),因为私有函数fire()未执行时,变量memory时undefined,执行过fire()后,memory = options.memory && data;即options.memory必须为true,add()才会调用私有函数fire()。
当执行过私有函数fire()后,lock()函数没有限制add()函数中调用私有函数fire()。
lock()函数将禁止使用callbacks.fire():在callbacks.fire()之前调用callbacks.lock(),此时memory是undefined,相当于调用了disable(),在callbacks.fire()之后调用callbacks.lock(),( !fired || stack )是false,callbacks.fire()禁止使用,
总之,callbacks.lock()出现后,callbacks.fire()都会作废。
lock: function() {stack = undefined;if ( !memory ) {self.disable();}return this;},
self下的fire()和fireWith():
参数once的作用体现:
stack = !options.once && [],
当$.Callbacks('once')时,stack=false,
callbacks.fire()
callbacks.fire()有两个时只能触发一次因为第一个callbacks.fire()执行后,fired=true,( !fired || stack )值是false
fireWith()就不能调用fire()。
在回调函数中执行callbacks.fire(),先不调用私有函数fire(),先将上下文和参数push到stack数组中,私有函数fire中发现,数组stack有内容,则将内容取出,作为fire()的参数,并执行fire()。
fire: function() {self.fireWith( this, arguments );return this;},
fireWith: function( context, args ) {if ( list && ( !fired || stack ) ) {//1.当list为undefined时,直接返回this//2.如果执行过callbacks.fire(),并且stack = undefined,直接返回this//但是在add()函数中,当memory为真时,可以调用fire()args = args || [];args = [ context, args.slice ? args.slice() : args ];if ( firing ) {//在回调函数中执行callbacks.fire(),先不调用私有函数fire()。例8stack.push( args );} else {fire( args );}}return this;},
私有函数fire():
fire = function( data ) {memory = options.memory && data;fired = true;firingIndex = firingStart || 0;firingStart = 0;firingLength = list.length;firing = true;//当list为undefined时,不能执行for循环语句,也就不能执行回调函数for ( ; list && firingIndex < firingLength; firingIndex++ ) {//data[ 1 ]表示callbacks.fire(123)中的参数123,此参数将作为回调函数的参数if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {memory = false; // To prevent further calls using addbreak;}}firing = false;if ( list ) {//当list为undefined时,不进一下行任何操作if ( stack ) {//var callbacks = $.Callbacks('不是once');if ( stack.length ) {fire( stack.shift() );}} else if ( memory ) {//var callbacks = $.Callbacks('once memory');list = [];} else {//var callbacks = $.Callbacks('once');self.disable();}}},
例8:结果是无限循环输出1, 2 ,1 ,2...,而不是1 ,1 ,1...
var callbacks = $.Callbacks(); function a(){ console.log(1); } function b(){ callbacks.fire(); console.log(2); } callbacks.add(a,b); callbacks.fire();
如果想要只循环一次,则需要设置一个开关:
var oBtn = true;var callbacks = $.Callbacks(); function a(){ console.log(1); } function b(){ if(oBtn){ callbacks.fire(); oBtn = false; } console.log(2); } callbacks.add(a,b); callbacks.fire();//1,2,1,2
- jQuery callback源码分析
- JQuery之Callback源码分析
- nginx源码分析—core模块callback
- nginx源码分析—core模块callback
- nginx源码分析—core模块callback
- ngx源码分析--core模块以及callback
- [ jQuery ] jQuery 源码分析!
- jQuery( callback )
- Jquery源码分析(一)
- jQuery 源码分析
- JQuery 源码分析 -1
- jQuery源码分析
- jquery源码分析
- Jquery queue源码分析
- jQuery源码分析
- Jquery源码 基础分析
- jquery源码分析
- jQuery 源码分析
- java中的装饰者模式
- 链表面试题精讲
- mongDB使用小技巧
- How to Switchover&Failover in DataGuard-11G
- 深度学习在OCR中的应用
- jQuery callback源码分析
- 高斯消元(Gauss elimination)的算法实现
- 调试——Debug
- java基础数组案例
- 9.12第一轮扫荡战果
- Java 线程同步基础类 LockSupport 解析
- Java实现几种常见排序方法
- 【CUGBACM15级BC第35场 A】hdu 5194 DZY Loves Balls
- JAVA入门学习小结(二)枚举类型