<!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就是这些代码的需求。

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

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

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

  1. jquery.Callbacks的实现

    前言 本人是一个热爱前端的菜鸟,一直喜欢学习js原生,对于jq这种js库,比较喜欢理解他的实现,虽然自己能力有限,水平很低,但是勉勉强强也算是能够懂一点吧,对于jq源码解读系列,博客园里有很多,推荐大 ...

  2. jQuery.Callbacks之demo

    jQuery.Callbacks是jquery在1.7版本之后加入的,是从1.6版中的_Deferred对象中抽离的,主要用来进行函数队列的add.remove.fire.lock等操作,并提供onc ...

  3. jQuery 2.0.3 源码分析 回调对象 - Callbacks

    源码API:http://api.jquery.com/jQuery.Callbacks/ jQuery.Callbacks()是在版本1.7中新加入的.它是一个多用途的回调函数列表对象,提供了一种强 ...

  4. jquery的回调对象Callbacks详解

    Callbacks : 对函数的统一管理 Callbacks的options参数接受4个属性,分别是once : 只执行一次momery : 记忆stopOnFalse : 强制退出循环unique ...

  5. $.Callbacks()

    <script> var cb = $.Callbacks(); //Callbacks(option) 有4个参数,可以多个参数写一起,空格分隔开 //once 多个fire() 只触发 ...

  6. 深入jQuery中的Callbacks()

    引入 初看Callbacks函数很不起眼,但仔细一瞅,发现Callbacks函数是构建jQuery大厦的无比重要的一个基石.jQuery中几乎所有有关异步的操作都会用到Callbacks函数. 为什么 ...

  7. JQuery源码解析--callbacks

    (function (global, factory) { factory(global); })(this, function (window, noGlobal) { var rootjQuery ...

  8. 读jQuery源码 - Callbacks

    代码的本质突出顺序.有序这一概念,尤其在javascript——毕竟javascript是单线程引擎. javascript拥有函数式编程的特性,而又因为javascript单线程引擎,我们的函数总是 ...

  9. jQuery回调、递延对象总结(上篇)—— jQuery.Callbacks

    前言: 作为参数传递给另一个函数执行的函数我们称为回调函数,那么该回调又是否是异步的呢,何谓异步,如:作为事件处理器,或作为参数传递给 (setTimeout,setInterval)这样的异步函数, ...

  10. jQuery.Callbacks 源码解读二

    一.参数标记 /* * once: 确保回调列表仅只fire一次 * unique: 在执行add操作中,确保回调列表中不存在重复的回调 * stopOnFalse: 当执行回调返回值为false,则 ...

随机推荐

  1. 调用css时,用link 和 @import url 有什么区别

    加载css link与@import的区别: 其实 link 与 @import 在显示效果上还是有很大区别的,基本上来看 link 的加在会在页面显示之前全部加在完全,而 @import 会是读取完 ...

  2. Linux系统的中断、系统调用和调度概述【转】

    转自:http://blog.csdn.net/yanlinwang/article/details/8169725 版权声明:本文为博主原创文章,未经博主允许不得转载. 最近学习Linux操作系统, ...

  3. Hive文件格式

    hive文件存储格式包括以下几类: 1.TEXTFILE 2.SEQUENCEFILE 3.RCFILE 4.ORCFILE(0.11以后出现) 其中TEXTFILE为默认格式,建表时不指定默认为这个 ...

  4. json-encode()怎么进行解码呢?

    解决中文的一种方法就是先将中文转换为另一种编码格式,然后再使用json_encode(),最后再用解码把json串进行解码.还有一种方式就在php新版本中得到了解决,在下面的代码为展示. 以下为代码示 ...

  5. ActiveMQ 安装异常

    解决方式: 1.确认计算机主机名名称没有下划线: 2.如果是win7,停止ICS(运行-->services.msc找到Internet Connection Sharing (ICS)服务,改 ...

  6. 《Linux/Unix系统编程手册》

    TCP的TIME_WAIT状态,超时时间为2倍MSL(IP报文超过TTL前最大生存时间,BSD规范为30s,RFC1122建议为2分钟).

  7. tomcat清除缓存

    方案一:点击进入解压后的tomcat,找到work文件夹,.此文件下有个catalina目录(tomcat小名叫catalina),work目录下的文件都可以删除.如果我们先前发布的一个项目有错,大家 ...

  8. ACM题目————数独

    描述 数独是一种运用纸.笔进行演算的逻辑游戏.玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行.每一列.每一个3*3宫内的 数字均含1-9,不重复. 每一道合格的数独谜题都有 ...

  9. 跨站点脚本编制实例(AppScan扫描结果)

    最近工作要求解决下web的项目的漏洞问题,扫描漏洞是用的AppScan工具,其中有很多是关于跨站点脚本编制问题的.下面就把这块东西分享出来. 原创文章,转载请注明 ------------------ ...

  10. poj3263 Tallest Cow

    题意略去. 考虑给定的R对pair(A, B). 即A能看见B,这意味着B不比A低,并且区间内部的所有元素的高度严格小于A的高度. 我们规定区间的方向:若A > B,为反方向,反之称为正方向. ...