jQuery源码笔记——回调对象

回调对象是一个多用途的回调列表对象,提供了强大的的方式来管理回调函数列表。

最简单的缓存对象

function Callbacks(){
    var list = [],
    self = {
        add: function(fn){
            list.push(fn);
        },
        remove: function(fn){
            var  index;
            if((index = list.indexOf(fn)) > -1){
                list.splice( index, 1 );
            }
        },
        fire: function(value){
            for(var i in list){
                list[i](value);
            }
        },
    }
    return self;
}
var callbacks = Callbacks();
function fn1( value ) {
    console.log( value );
}
callbacks.add(fn1);
callbacks.fire( "foo!" );//foo!
callbacks.remove(fn1);
callbacks.fire( "foo!" );//nothing

回调对象是为了将回调函数统一管理,如添加,删除,调用等功能。

在jQuery当中,除了实现基本的管理,还提供了由Callbacks参数决定的回调对象的模式。这四个属性有once,memory,unique,stopOnFalse;

once的实现

function Callbacks( options ){
    var object = {};
    object[options] = true;
    options = object;
    var list = [],
    self = {
        add: function(fn){
            if ( list ) {
                list.push(fn);
            }
        },
        remove: function(fn){
            if ( list ) {
                var  index;
                if((index = list.indexOf(fn)) > -1){
                    list.splice( index, 1 );
                }
            }
        },
        fire: function(value){
            for(var i in list){
                list[i](value);
            }
            //在Once模式下,当fire过一次后清空回调函数列表。
            if( options.once ){
                list = undefined;
            }
        },
    }
    return self;
}
var callbacks = Callbacks( "once" );
function fn1( value ) {
    console.log( value );
}
callbacks.add(fn1);
callbacks.fire( "foo!" );//foo!
callbacks.fire( "foo!" );//nothing

在once模式下,fire过一次后,清空回调函数列表。

memory实现

function Callbacks( options ){
    var object = {};
    object[options] = true;
    options = object;
    var list = [],
    firingStart = 0,
    memory;
    self = {
        add: function(fn){
            if ( list ) {
                list.push(fn);
            }
            //如果存在记忆的参数,则直接调用fire
            if( memory ){
                self.fire( memory );
            }
        },
        remove: function(fn){
            if ( list ) {
                var  index;
                if((index = list.indexOf(fn)) > -1){
                    list.splice( index, 1 );
                }
            }
        },
        fire: function(value){
            //保存当前长度
            var start = list.length;
            for( ; firingStart < list.length;firingStart++){
                list[firingStart](value);
            }
            //在memory模式下,记忆参数,并修改add时调用列表的起始位置。
            if( options.memory ){
                firingStart = start;
                memory = value
            }
        },
    }
    return self;
};
function fn1( value ) {
    console.log( value );
}
function fn2( value ) {
    fn1("fn2 says: " + value);
    return false;
}
var callbacks = Callbacks( "memory" );
callbacks.add( fn1 );
callbacks.fire( "foo" );
callbacks.add( fn2 );

在memory下,记忆上次调用的参数,和已经执行了函数的位置,当有新函数add时,直接调用。

unique实现

function Callbacks( options ){
    var object = {};
    object[options] = true;
    options = object;
    var list = [],
    firingStart = 0,
    memory;
    self = {
        add: function(fn){
            if ( list ) {
                //在unique模式下,当函数已存在,则不添加。
                if ( !options.unique || !(list.indexOf(fn) > -1))
                    list.push(fn);
            }
        },
        remove: function(fn){
            if ( list ) {
                var  index;
                if((index = list.indexOf(fn)) > -1){
                    list.splice( index, 1 );
                }
            }
        },
        fire: function(value){
            for( ; firingStart < list.length;firingStart++){
                list[firingStart](value);
            }
        },
    }
    return self;
};
function fn1( value ) {
    console.log( value );
}
var callbacks = Callbacks( "unique" );
callbacks.add( fn1 );
callbacks.add( fn1 );
callbacks.fire( "bar" );//bar

主要针对add函数的判断

stopOnFalse的实现

function Callbacks( options ){
    var object = {};
    object[options] = true;
    options = object;
    var list = [],
    firingStart = 0,
    memory;
    self = {
        add: function(fn){
            if ( list ) {
                list.push(fn);
            }
        },
        remove: function(fn){
            if ( list ) {
                var  index;
                if((index = list.indexOf(fn)) > -1){
                    list.splice( index, 1 );
                }
            }
        },
        fire: function(value){
            for( ; firingStart < list.length;firingStart++){
                if( !list[firingStart](value) )
                    break;
            }
        },
    }
    return self;
};
function fn1( value ) {
    console.log( value );
    return false;
}
function fn2( value ){
    fn1( "fn2 says: " + value );
    return false;
}
var callbacks = Callbacks( );
callbacks.add( fn1 );
callbacks.add( fn2 );
callbacks.fire( "bar" );

每次fire判断是否返回的是false,是则停止继续调用。

时间: 2024-10-13 00:26:18

jQuery源码笔记——回调对象的相关文章

jQuery源码笔记——缓存对象

缓存对象可以注册多个回调到回调队列, 调用回调队列,准备代替任何同步或异步函数的成功或失败状态. 其原理是将回调函数保存到一个数组当中,等到触发时再调用. 一个简单的,只解决成功状态下的缓存实例 function myDeferred(){ var arr = []; return { done: function(a){ arr.push(a); }, solve : function(){ arr.shift()(); } } } var a = myDeferred(); a.done(f

jquery 源码笔记:

1.使用了jquery,但是觉得了解 jquery的源码才能 更容易知道怎么使用,所以在网上找了一些 jquery的源码 笔记 还有看了 妙味课堂 的 一部分视频,现在写一些总结. 一.  jquery的 总体架构: 1.jquery 有良好的对外接口,  window.jQuery = window.$ = jQuery; 现在 是 通过jquery 2.0.3 源码的分析: (21,94)  21—94行, 定义了一些变量和函数,   jQuery = function(); (96,283

转载Aaron博客 ---- jQuery 2.0.3 源码分析 回调对象 - Callbacks

源码API:http://api.jquery.com/jQuery.Callbacks/ jQuery.Callbacks()是在版本1.7中新加入的.它是一个多用途的回调函数列表对象,提供了一种强大的方法来管理回调函数队列. 那么jQuery.Callbacks使用场景在哪里? 在很多时候需要控制一系列的函数顺序执行.那么一般就需要一个队列函数来处理这个问题 我们看一段代码 function Aaron(List, callback) { setTimeout(function() { va

jQuery 源码: 延迟对象补充。

// Deferred helper (3132)when 是延迟对象 Deferred的一个辅助方法. var dfd = $.Deferred(); //创建延迟对象 dfd.done(); dfd.fail(); //使用: $.when().done(); $.when().fail();   when的返回值,是一个延迟对象. 源码: return deferred.promise(); 举个例子:when可以等待多个延迟对象都成功后,触发成功.例子:(1) 成功必须多个都成功. fu

jquery源码笔记(三): jquery.prototype的一些方法 和属性 init

jquery.fn = jquery.prototype = { 添加实例属性和方法, jquery: 版本, constructor: 修正指向问题 init(): 初始化 和 参数管理 selector:存储选择字符串 length: this 对象的长度 toArray(): 转数组 get(): 转原生集合 pushStack(): jquery 对象入栈 each()  :  便利集合 ready():DOM加载的接口 slice(): 集合的截取 first(): 集合的第一项 la

javascript 跟Aaron大神学习jquery源码笔记

/* 通过new操作符构建一个对象,一般经过四步: A.创建一个新对象 B.将构造函数的作用域赋给新对象(所以this就指向了这个新对象) C.执行构造函数中的代码 D.返回这个新对象 最后一点就说明了,我们只要返回一个新对象即可. 其实new操作符主要是把原型链跟实例的this关联起来,这才是最关键的一点, 所以我们如果需要原型链就必须要new操作符来进行处理.否则this则变成window对象了. */ /* var $$ = ajQuery = function(selector) { t

jquery源码笔记(四): jquery.extend=jquery.fn.extend

extend()  方法,   合并两个或更多对象的属性到第一个对象中,jQuery后续的大部分功能都通过该函数扩展, 当参数只有一个对象时,则将对象的属性添加到jQuery对象中. jquery 中扩展插件的形式:  2种方法 $.extend({ //扩展工具方法 aaa:function(){ alert(10); }, bbb:function(){ alert(20) } }); $.fn.extend({ //扩展jquery实例方法 aaa:function(){ alert("f

jQuery源码笔记——四

each()实现 var jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context ); }; jQuery.fn = jQuery.prototype = { selector: "", init: function(selector){ //仍然是mini的选择器. var result = document.querySelectorAll(selector); fo

jQuery源码笔记——三

将类数组对象转化为数组对象 javascript中有许多类数组对象,比如HTMLCollection,NodeList,arguments.她们的特点是和数组一样有length属性,并且有0,1,2这样的位置属性.在代码编写中我们经常需要将他们转化为数组对象. //mini类数组对象 var arrayLike = { 0: "a", 1: "b", 2: "c", length: 3 } console.log(Array.prototype.