JQuery之Callback源码分析
来源:互联网 发布:2017年流行什么网络语? 编辑:程序博客网 时间:2024/05/23 20:11
主要对JQuery的Callback部分进行讲解
Callback源代码
var optionsCache = {};//主要作用是 once memory unique stopOnFalse//once: 确保回调队列中的回调函数被执行一次 Deferred会用到//memory:保留上一次执行的值,那怕后续添加一个回调函数,也确保调用上一次记录的值为参数 Deferred会用到//unique:确保同一个函数仅被添加一次//stopOnFalse:如果回调函数队列中有一个回调函数执行后返回false就立即中断剩下的回调函数执行function createOptions(options) { var object = optionsCache[options] = {}; //core_rnotwhite = /\S+/g, //var core_rnotwhite = /\S+/g; "one test ".match(core_rnotwhite) //["one", "test"] jQuery.each(options.match(core_rnotwhite) || [], function (_, flag) { object[flag] = true; }); return object;}//主体部分//比如传入 "once memory"//optionsCache["once memory"]={},optionsCache["once memory"]["once"]=true,optionsCache["once memory"]["memory"]=true;jQuery.Callbacks = function (options) { options = typeof options === "string" ? (optionsCache[options] || createOptions(options)) : jQuery.extend({}, options); var firing,//标志位,如果队列正在执行 flag to know if list is currently firing memory,//最后执行的值 last fire value fired,//标志位,如果队列已经执行 flag to know if list was already fired firingLength,//执行时,整个队列长度 end of the loop when firing firingIndex,//回调队列正在执行的当前函数的队列索引 index of currently firing callback firingStart,//真正执行回调队列中 的回调函数在队列中的起始位置 first callback to fire list = [],//实际的回调队列 actual callback list stack = !options.once && [],//栈保存可以多次被执行的队列 //stack : 当"once memory"的时候,stack=false;当"memory"的时候,stack=[];这个主要是针对once来说的 fire = function (data) { //初始化标志信息 memory = options.memory && data; //&&短操作符,如果碰到false(可以转化为false的)就去那个值,如果没有碰到就去最后一个 fired = true; firingIndex = firingStart || 0; //||短操作符,如果碰到true(可以转化为true的)就取那个值,取第一个为true的值,否则也是取最后一个 firingStart = 0; firingLength = list.length; firing = true; for (; list && firingIndex < firingLength; firingIndex++) { //队列中的函数执行,看回调是否阻止当执行的函数返回false的时候,是否停止对后续回调的调用 当有阻止模式时 if (list[firingIndex].apply(data[0], data[1]) === false && options.stopOnFalse) { memory = false; break; } } firing = false; //执行完回调函数后,对后续队列进行处理,主要是针对几种模式,分别处理 if (list) { if (stack) {//当栈中有数据时,即是非 once模式时 if (stack.length) { fire(stack.shift()); } } else if (memory) {//当有记忆模式时 list = []; } else { //其他情况 self.disable(); } } }, //真实的callback对象 slef = { //添加一个callback 或者 callback 集合到 回调队列中去 add: function () { if (list) { //我们保持当前长度 var start = list.length; //立即执行第一次调用 (function add(args) { jQuery.each(args, function (_, arg) { var type = jQuery.type(arg);//判断arguments数组中单个元素的类型 if (type === "function") { //当为非唯一模式和队列没有arg回调函数时 if (!options.unique || !self.has(arg)) { list.push(arg); } } else if (arg && arg.length && type !== "string") {//当arg为数组并且不是字符型,即为[]类型 add(arg); //递归添加 } }); })(arguments); //针对模式后续处理 if (firing) { firingLength = list.length; } else if (memory) { //当有记忆模式时候,后续添加的函数会被立即调用,使用上一次调用的参数 firingStart = start; fire(memory); } } return list; }, remove: function () { if (list) { jQuery.each(arguments, function (_, arg) { var index; //从0检索arg是否在list中 while ((index = jQuery.inArray(arg, list, index)) > -1) { list.splice(index, 1); //调整firing的长度和索引 if (firing) { if (index <= firingLength) { firingLength--; } if (index <= firingIndex) { firingIndex--; } } } }); } return this; }, //函数是否在回调队列中 has: function (fn) { return fn ? jQuery.inArray(fn, list) > -1 : !!(list && list.length); }, //清空队列 empty: function () { list = []; firingLength = 0; return this; }, //使队列不够做任何事情了,已经undefined了 disable: function () { list = stack = memory = undefined; return this; }, //是否是可用状态 disabled: function () { return !list; }, //锁定栈为他的当前状态 lock: function () { stack = undefined; if (!memory) {//当为记忆模式时候 self.disable(); } return this; }, //栈的当前状态 locked: function () { return !stack; }, //调用回调集合并且传递上下文和参数信息过去 fireWith: function (context, args) { args = args || []; //args为数组的时候就让其为数组,当不为数组的时候把它变为数组 args = [context, args.slice ? args.slice() : args]; if (list && (!fired || stack)) { if (firing) {//当正在执行时,把arguments推到栈中去 stack.push(args); } else {//当为非执行状态的时候,就立马执行调用队列中的回调,并且把回调参数传递进去 // 这里的fire是调用上面的fire,而非下面的fire //因为fire还在后面定义的 //所以下面的fire是对fireWith不可见的 fire(args); } } return this; }, //调用回调使用调用给的参数 fire: function () { slef.fireWith(this, arguments); return this; }, //回调是否已经被调用过了 fired: function () { return !!fired; } }; return self;}
使用方式见
JQuery官方Callback使用
0 0
- JQuery之Callback源码分析
- jQuery callback源码分析
- jQuery 之 Callback 实现
- jQuery 之 Callback 实现
- 温故而知新之JQuery-CallBack
- jQuery 之 Callback 实现
- jquery源码分析之Callbacks
- jquery 源码分析之Deferred
- jQuery源码分析之ajaxTransport
- jQuery源码分析之jQuery.makeArray函数
- jQuery源码分析之Event事件分析
- jQuery源码分析之Event事件分析
- nginx源码分析—core模块callback
- nginx源码分析—core模块callback
- nginx源码分析—core模块callback
- ngx源码分析--core模块以及callback
- jQuery源码分析之jQuery中常用正则表达式分析
- jQuery源码分析之on方法
- DOM对象转为Jquery对象 Jquery对象转为DOM对象
- 关于Genymotion启动异常、virtualbox 不能为虚拟电脑打开一个新任务/解决Genymotion出现Unable to load VirtualBox engine的问题
- ExecutorService生命周期
- leaflet加载百度地图
- bootstrap中popover.js(弹出框)使用总结+案例
- JQuery之Callback源码分析
- 持续集成 之 Jenkins插件 Multiple SCMs Plugin
- Ionic新建项目(以Android为例)
- [编程之美-02]把二元查找树变成为排序的双向链表
- Server.MapPath 的使用方法
- Java thread中的callback和Future的简单使用
- 互斥锁和条件变量
- Redis的安装,以及设置开机自启动
- 由浅入深之Dialog的基本弹框