模仿$.Callbacks实现

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body>
        1.add的参数兼容,比如cb.add(fn1).add(fn2)等同于add(fn1,fn2)等同于add([fn1,fn2])。
        2.$.Callbacks("memory"),第一次fire,执行之前的函数队列。fire之后add的时候,就执行加入的函数。
        3.$.Callbacks("unique"),add的时候判断当前函数,是否已存于执行队列中。
        4.$.Callbacks("once"),第一次fire的时候,打个标记表明once了。第二次fire的时候,有once,就不执行队列。
        5.$.Callbacks("stopOnFalse"),判断执行队列中函数的执行结果,为false,则中断函数队列的遍历执行。
        6.$.Callbacks("memory once"),字符串对象化,使得字符串顺序变换也没关系。之后各回各家,该干嘛干嘛去。
        7.$.Callbacks是一个对象工厂。
        8.$.Callbacks的lock和disable的区别。lock只是不再add,但还能fire。disable不仅不能add,连fire也不行。
        9.$.Callbacks的remove方法,就是从队列去除指定函数。
        10.fire的时候可以指定上下文
    </body>
    <script type="text/javascript">
        function showType(type, obj) {
            var clas = Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
            return obj !== undefined && obj !== null && clas === type;
        }

        var $={};

        // 依赖  类型判断showType,遍历处理
        $.Callbacks = function(strArg){

            var list = [];
            var fired_flag=false;
            var lock_flag=false ,disable_flag = false;
            var str_list = strArg.split(" ");
            var fire_args = [];

            var cbArg_obj = {
                "once":false,
                "unique":false,
                "memory":false,
                "stopOnFalse":false
            };

            for(var i=0,l=str_list.length; i<l; i++){
                cbArg_obj[str_list[i]] = true;
            }

            var once_flag = cbArg_obj["once"],
            unique_flag= cbArg_obj["unique"],
            memory_flag= cbArg_obj["memory"],
            stopOnFalse_flag= cbArg_obj["stopOnFalse"];

            var self = {
                "add":function(){
                    if(lock_flag || disable_flag){
                        return;
                    }
                    // 参数兼容
                    var arg = arguments;
                    (function add(arg){
                        for(var i=0,l = arg.length; i< l; i++){
                            var argItem = arg[i];
                            if(list.indexOf(argItem)>-1 && unique_flag){
                                return;
                            }
                            if(showType("function",argItem) ){
                                list.push(argItem);
                                if(memory_flag && fired_flag){
                                    argItem.apply(null,fire_args);
                                }
                            }
                            else if(showType("array",argItem)){
                                add(argItem);
                            }
                        }
                    })(arg);

                    // 为了链性调用
                    return this;
                },
                "fire":function(){
                    if( (once_flag && fired_flag) || disable_flag){
                        return;
                    }
                    if(arguments.length){
                        fire_args = arguments || [];
                    }
                    for(var i =0,l= list.length; i< l; i++){
                        if( (list[i].apply(this,fire_args) == false) && stopOnFalse_flag){
                            break;
                        }
                    }
                    fired_flag = true;
                },
                "remove":function(fn){
                    for(var i=0,l= list.length; i<l; i++){
                        if(list[i] == fn){
                            list.splice(i,1);
                        }
                    }
                },
                "lock":function(){
                    lock_flag = true;
                },
                "disable":function(){
                    disable_flag = true;
                }
            };
            return self;
        };

        function fn1(){
            alert(1);
        }

        function fn2(){
            alert(2);
        }
        function fn3(){
            alert(3);
        }
        function fn4(){
            alert(4);
        }
        function fnThis(arg){
            alert(arg);
        }
        function fnFalse(){
            return false;
        }
        var cb = $.Callbacks("once memory");
        cb.add(fn1).add(fn2).add(fn4);
        cb.fire("hi");
        cb.add(fnThis);
        cb.fire("aaa");
    </script>
</html>

源代码阅读这件事:

第一步,查看API。先明白这些API怎么用,因为API就是这些代码的需求。

第二步,思考为什么这么写。一个需求实现,可以有多种实现方式。但是作者偏偏用这种,是为了代码性能优化、解耦,抑或偷懒?

第三步,自己重新实现。有时候,第二步你怎么想,也想不出作者这样写的原因。自己动手重新实现,实现过程中,才更能理解作者的用心。

时间: 2024-07-29 12:45:22

模仿$.Callbacks实现的相关文章

jquery.Callbacks的实现

前言 本人是一个热爱前端的菜鸟,一直喜欢学习js原生,对于jq这种js库,比较喜欢理解他的实现,虽然自己能力有限,水平很低,但是勉勉强强也算是能够懂一点吧,对于jq源码解读系列,博客园里有很多,推荐大神  艾伦的jq系列,在这里,我仅仅是分享一下我对jq里的Callbacks模块的理解与详细介绍一下我自己仿jq实现的一个callback功能. 功能介绍 jq的Callbacks模块主要是为其他模块提供服务的,他就像一个温柔的小女人,在背后默默地付出.Deferred就像一个巨人,在jq中那么的突

jQuery中的$.Callbacks回调

前言 在js中使用回调函数是很常见的.但是当触发一个事件时需要同时执行多个回调函数时,我们可能就需要一个队列来把这些回调函数存放起来,当事件触发时按照队列的先进先出原则依次调用这些回调函数.在jQuery中就是使用$.Callbacks这个工具方法来管理回掉函数队列的. 1 function fn1(){ 2 console.log(1); 3 } 4 function fn2(){ 5 console.log(2); 6 } 7 var callbacks = $.Callbacks(); 8

linux系统日志__ratelimit: N callbacks suppressed

报错 今天线上遇到故障,php进行因为段错误退出了,系统日志中的kernel报错如下: Feb 25 22:25:11 web_server_01 kernel: __ratelimit: 250 callbacks suppressed Feb 25 22:25:11 web_server_01 kernel: php-fpm[25942]: segfault at 2c6 ip 00000000000002c6 sp 00007fffdcf9e798 error 14 in php-fpm[

jQuery.callbacks 注释

1 (function( jQuery ) { 2 3 // String to Object flags format cache 4 var flagsCache = {}; 5 6 // Convert String-formatted flags into Object-formatted ones and store in cache 7 // 将字符串形式的flags转换成对象形式,并且存到cache中,例: "once memory" => {"once&

jQuery 源码callbacks

callbacks工具方法,作用是函数回调的统一管理 jQuery.Callbacks = function( options ) { } 使用:类似于事件绑定,fire之后,之前绑定的方法,都执行. 观察者模式. function aaa() { alert(1); } function bbb() { alert(2); } function ccc() { alert(3) } var cb = $.Callbacks(); cb.add(aaa); cb.add(bbb); cb.add

Item 62: Use Nested or Named Callbacks for Asynchronous Sequencing

Item  61  shows  how  asynchronous  APIs  perform  potentially  expensive  I/O  operations  without  blocking  the  application  from  continuing doing work and processing other input. Understanding the order of operations of asynchronous programs ca

jquery源码01---(2880 , 3042) Callbacks : 回调对象 : 对函数的统一管理

// optionsCache : { 'once memory' : { once : true , memory : true } } var optionsCache = {}; // once memory,options.match( core_rnotwhite )=[once, memory],function( _, flag )={once:true,memory:true} function createOptions( options ) { var object = op

jQuery源码解读第5章---对Callbacks的解读

jQuery.Callbacks() 是一个多用途的回调函数列表对象 提供了一种强大的方法来管理回调函数队列 先来看看Callbacks的常见的用法 1-------不带参数 先看看不用回调函数的例子 eq function a1(){ console.log('a1') } (function(){ function a2(){ console.log('a2') } })() a1() // a1 a2() //就不行了 这时候我们就可以使用回调函数Callbacks 了 var dfd1

JQuery源码解析--callbacks

1 (function (global, factory) { 2 factory(global); 3 })(this, function (window, noGlobal) { 4 var rootjQuery; 5 var class2type = {}; 6 var toString = class2type.toString; 7 var arr = []; 8 var indexOf = arr.indexOf; 9 var myJQuery = function (selecto