摘要:jQuery.Callbacks()是在版本1.7中新加入的。它是一个多用途的回调函数列表对象,提供了一种强大的方法来管理回调函数队列。

小宝典致力于为广大程序猿(媛)提供高品质的代码服务,请大家多多光顾小站,小宝典在此谢过。

jQuery.Callbacks()是在版本1.7中新加入的。它是一个多用途的回调函数列表对象,提供了一种强大的方法来管理回调函数队列。

1、使用场景:

 var callbacks = $.Callbacks();    callbacks.add(function() {     alert('a');   })    callbacks.add(function() {     alert('b');   })    callbacks.fire(); //输出结果: 'a' 'b'

便捷的处理参数

once: 确保这个回调列表只执行( .fire() )一次(像一个递延 Deferred).

memory: 保持以前的值,将添加到这个列表的后面的最新的值立即执行调用任何回调 (像一个递延 Deferred).

unique: 确保一次只能添加一个回调(所以在列表中没有重复的回调).

stopOnFalse: 当一个回调返回false 时中断调用

例如:

 var callbacks = $.Callbacks('once');    callbacks.add(function() {     alert('a');   })    callbacks.add(function() {     alert('b');   })    callbacks.fire(); //输出结果: 'a' 'b'   callbacks.fire(); //未执行

2、jQuery.Callbacks()的API

 callbacks.add()        回调列表中添加一个回调或回调的集合。 callbacks.disable()    禁用回调列表中的回调 callbacks.disabled()   确定回调列表是否已被禁用。  callbacks.empty()      从列表中删除所有的回调. callbacks.fire()       用给定的参数调用所有的回调 callbacks.fired()      访问给定的上下文和参数列表中的所有回调。  callbacks.fireWith()   访问给定的上下文和参数列表中的所有回调。 callbacks.has()        确定列表中是否提供一个回调 callbacks.lock()       锁定当前状态的回调列表。 callbacks.locked()     确定回调列表是否已被锁定。 callbacks.remove()     从回调列表中的删除一个回调或回调集合。

源码分析:

 jQuery.Callbacks = function(options) {      // Convert options from String-formatted to Object-formatted if needed     // (we check in cache first)     //通过字符串在optionsCache寻找有没有相应缓存,如果没有则创建一个,有则引用     //如果是对象则通过jQuery.extend深复制后赋给options。     options = typeof options === "string" ?         (optionsCache[options] || createOptions(options)) :         jQuery.extend({}, options);      var // Last fire value (for non-forgettable lists)     memory, // 最后一次触发回调时传的参数          // Flag to know if list was already fired         fired, // 列表中的函数是否已经回调至少一次          // Flag to know if list is currently firing         firing, // 列表中的函数是否正在回调中          // First callback to fire (used internally by add and fireWith)         firingStart, // 回调的起点          // End of the loop when firing         firingLength, // 回调时的循环结尾          // Index of currently firing callback (modified by remove if needed)         firingIndex, // 当前正在回调的函数索引          // Actual callback list         list = [], // 回调函数列表          // Stack of fire calls for repeatable lists         stack = !options.once && [], // 可重复的回调函数堆栈,用于控制触发回调时的参数列表          // Fire callbacks// 触发回调函数列表         fire = function(data) {             //如果参数memory为true,则记录data             memory = options.memory && data;             fired = true; //标记触发回调             firingIndex = firingStart || 0;             firingStart = 0;             firingLength = list.length;             //标记正在触发回调             firing = true;             for (; list && firingIndex < firingLength; firingIndex++) {                 if (list[firingIndex].apply(data[0], data[1]) === false && options.stopOnFalse) {                     // 阻止未来可能由于add所产生的回调                     memory = false; // To prevent further calls using add                     break; //由于参数stopOnFalse为true,所以当有回调函数返回值为false时退出循环                 }             }             //标记回调结束             firing = false;             if (list) {                 if (stack) {                     if (stack.length) {                         //从堆栈头部取出,递归fire                         fire(stack.shift());                     }                 } else if (memory) { //否则,如果有记忆                     list = [];                 } else { //再否则阻止回调列表中的回调                     self.disable();                 }             }         },         // Actual Callbacks object         // 暴露在外的Callbacks对象,对外接口         self = {             // Add a callback or a collection of callbacks to the list             add: function() { // 回调列表中添加一个回调或回调的集合。                 if (list) {                     // First, we save the current length                     //首先我们存储当前列表长度                     var start = list.length;                     (function add(args) { //jQuery.each,对args传进来的列表的每一个对象执行操作                         jQuery.each(args, function(_, arg) {                             var type = jQuery.type(arg);                             if (type === "function") {                                 if (!options.unique || !self.has(arg)) { //确保是否可以重复                                     list.push(arg);                                 }                                 //如果是类数组或对象,递归                             } else if (arg && arg.length && type !== "string") {                                 // Inspect recursively                                 add(arg);                             }                         });                     })(arguments);                     // Do we need to add the callbacks to the                     // current firing batch?                     // 如果回调列表中的回调正在执行时,其中的一个回调函数执行了Callbacks.add操作                     // 上句话可以简称:如果在执行Callbacks.add操作的状态为firing时                     // 那么需要更新firingLength值                     if (firing) {                         firingLength = list.length;                         // With memory, if we're not firing then                         // we should call right away                     } else if (memory) {                         //如果options.memory为true,则将memory做为参数,应用最近增加的回调函数                         firingStart = start;                         fire(memory);                     }                 }                 return this;             },             // Remove a callback from the list             // 从函数列表中删除函数(集)             remove: function() {                 if (list) {                     jQuery.each(arguments, function(_, arg) {                         var index;                         // while循环的意义在于借助于强大的jQuery.inArray删除函数列表中相同的函数引用(没有设置unique的情况)                         // jQuery.inArray将每次返回查找到的元素的index作为自己的第三个参数继续进行查找,直到函数列表的尽头                         // splice删除数组元素,修改数组的结构                         while ((index = jQuery.inArray(arg, list, index)) > -1) {                             list.splice(index, 1);                             // Handle firing indexes                             // 在函数列表处于firing状态时,最主要的就是维护firingLength和firgingIndex这两个值                             // 保证fire时函数列表中的函数能够被正确执行(fire中的for循环需要这两个值                             if (firing) {                                 if (index <= firingLength) {                                     firingLength--;                                 }                                 if (index <= firingIndex) {                                     firingIndex--;                                 }                             }                         }                     });                 }                 return this;             },             // Check if a given callback is in the list.             // If no argument is given, return whether or not list has callbacks attached             // 回调函数是否在列表中.             has: function(fn) {                 return fn ? jQuery.inArray(fn, list) > -1 : !! (list && list.length);             },             // Remove all callbacks from the list             // 从列表中删除所有回调函数             empty: function() {                 list = [];                 firingLength = 0;                 return this;             },             // Have the list do nothing anymore             // 禁用回调列表中的回调。             disable: function() {                 list = stack = memory = undefined;                 return this;             },             // Is it disabled?             //  列表中否被禁用             disabled: function() {                 return !list;             },             // Lock the list in its current state             // 锁定列表             lock: function() {                 stack = undefined;                 if (!memory) {                     self.disable();                 }                 return this;             },             // Is it locked?             // 列表是否被锁             locked: function() {                 return !stack;             },             // Call all callbacks with the given context and arguments             // 以给定的上下文和参数调用所有回调函数             fireWith: function(context, args) {                 if (list && (!fired || stack)) {                     args = args || [];                     args = [context, args.slice ? args.slice() : args];                     //如果正在回调                     if (firing) {                         //将参数推入堆栈,等待当前回调结束再调用                         stack.push(args);                     } else { //否则直接调用                         fire(args);                     }                 }                 return this;             },             // Call all the callbacks with the given arguments             // 以给定的参数调用所有回调函数             fire: function() {                 self.fireWith(this, arguments);                 return this;             },             // To know if the callbacks have already been called at least once             // // 回调函数列表是否至少被调用一次             fired: function() {                 return !!fired;             }         };     return self; };

jQuery.Callbacks()的核心思想是 Pub/Sub 模式,建立了程序间的松散耦合和高效通信。

pub/sub (观察者模式) 的背后,总的想法是在应用程序中增强松耦合性。并非是在其它对象的方法上的单个对象调用。一个对象作为特定任务或是另一对象的活动的观察者,并且在这个任务或活动发生时,通知观察者。观察者也被叫作订阅者(Subscriber),它指向被观察的对象,既被观察者(Publisher 或 subject)。当事件发生时,被观察者(Publisher)就会通知观察者(subscriber)。

jQuery.Callbacks()是在版本1.7中新加入的。它是一个多用途的回调函数列表对象,提供了一种强大的方法来管理回调函数队列。

1、使用场景:

 var callbacks = $.Callbacks();    callbacks.add(function() {     alert('a');   })    callbacks.add(function() {     alert('b');   })    callbacks.fire(); //输出结果: 'a' 'b'

便捷的处理参数

once: 确保这个回调列表只执行( .fire() )一次(像一个递延 Deferred).

memory: 保持以前的值,将添加到这个列表的后面的最新的值立即执行调用任何回调 (像一个递延 Deferred).

unique: 确保一次只能添加一个回调(所以在列表中没有重复的回调).

stopOnFalse: 当一个回调返回false 时中断调用

例如:

 var callbacks = $.Callbacks('once');    callbacks.add(function() {     alert('a');   })    callbacks.add(function() {     alert('b');   })    callbacks.fire(); //输出结果: 'a' 'b'   callbacks.fire(); //未执行

2、jQuery.Callbacks()的API

 callbacks.add()        回调列表中添加一个回调或回调的集合。 callbacks.disable()    禁用回调列表中的回调 callbacks.disabled()   确定回调列表是否已被禁用。  callbacks.empty()      从列表中删除所有的回调. callbacks.fire()       用给定的参数调用所有的回调 callbacks.fired()      访问给定的上下文和参数列表中的所有回调。  callbacks.fireWith()   访问给定的上下文和参数列表中的所有回调。 callbacks.has()        确定列表中是否提供一个回调 callbacks.lock()       锁定当前状态的回调列表。 callbacks.locked()     确定回调列表是否已被锁定。 callbacks.remove()     从回调列表中的删除一个回调或回调集合。

源码分析:

 jQuery.Callbacks = function(options) {      // Convert options from String-formatted to Object-formatted if needed     // (we check in cache first)     //通过字符串在optionsCache寻找有没有相应缓存,如果没有则创建一个,有则引用     //如果是对象则通过jQuery.extend深复制后赋给options。     options = typeof options === "string" ?         (optionsCache[options] || createOptions(options)) :         jQuery.extend({}, options);      var // Last fire value (for non-forgettable lists)     memory, // 最后一次触发回调时传的参数          // Flag to know if list was already fired         fired, // 列表中的函数是否已经回调至少一次          // Flag to know if list is currently firing         firing, // 列表中的函数是否正在回调中          // First callback to fire (used internally by add and fireWith)         firingStart, // 回调的起点          // End of the loop when firing         firingLength, // 回调时的循环结尾          // Index of currently firing callback (modified by remove if needed)         firingIndex, // 当前正在回调的函数索引          // Actual callback list         list = [], // 回调函数列表          // Stack of fire calls for repeatable lists         stack = !options.once && [], // 可重复的回调函数堆栈,用于控制触发回调时的参数列表          // Fire callbacks// 触发回调函数列表         fire = function(data) {             //如果参数memory为true,则记录data             memory = options.memory && data;             fired = true; //标记触发回调             firingIndex = firingStart || 0;             firingStart = 0;             firingLength = list.length;             //标记正在触发回调             firing = true;             for (; list && firingIndex < firingLength; firingIndex++) {                 if (list[firingIndex].apply(data[0], data[1]) === false && options.stopOnFalse) {                     // 阻止未来可能由于add所产生的回调                     memory = false; // To prevent further calls using add                     break; //由于参数stopOnFalse为true,所以当有回调函数返回值为false时退出循环                 }             }             //标记回调结束             firing = false;             if (list) {                 if (stack) {                     if (stack.length) {                         //从堆栈头部取出,递归fire                         fire(stack.shift());                     }                 } else if (memory) { //否则,如果有记忆                     list = [];                 } else { //再否则阻止回调列表中的回调                     self.disable();                 }             }         },         // Actual Callbacks object         // 暴露在外的Callbacks对象,对外接口         self = {             // Add a callback or a collection of callbacks to the list             add: function() { // 回调列表中添加一个回调或回调的集合。                 if (list) {                     // First, we save the current length                     //首先我们存储当前列表长度                     var start = list.length;                     (function add(args) { //jQuery.each,对args传进来的列表的每一个对象执行操作                         jQuery.each(args, function(_, arg) {                             var type = jQuery.type(arg);                             if (type === "function") {                                 if (!options.unique || !self.has(arg)) { //确保是否可以重复                                     list.push(arg);                                 }                                 //如果是类数组或对象,递归                             } else if (arg && arg.length && type !== "string") {                                 // Inspect recursively                                 add(arg);                             }                         });                     })(arguments);                     // Do we need to add the callbacks to the                     // current firing batch?                     // 如果回调列表中的回调正在执行时,其中的一个回调函数执行了Callbacks.add操作                     // 上句话可以简称:如果在执行Callbacks.add操作的状态为firing时                     // 那么需要更新firingLength值                     if (firing) {                         firingLength = list.length;                         // With memory, if we're not firing then                         // we should call right away                     } else if (memory) {                         //如果options.memory为true,则将memory做为参数,应用最近增加的回调函数                         firingStart = start;                         fire(memory);                     }                 }                 return this;             },             // Remove a callback from the list             // 从函数列表中删除函数(集)             remove: function() {                 if (list) {                     jQuery.each(arguments, function(_, arg) {                         var index;                         // while循环的意义在于借助于强大的jQuery.inArray删除函数列表中相同的函数引用(没有设置unique的情况)                         // jQuery.inArray将每次返回查找到的元素的index作为自己的第三个参数继续进行查找,直到函数列表的尽头                         // splice删除数组元素,修改数组的结构                         while ((index = jQuery.inArray(arg, list, index)) > -1) {                             list.splice(index, 1);                             // Handle firing indexes                             // 在函数列表处于firing状态时,最主要的就是维护firingLength和firgingIndex这两个值                             // 保证fire时函数列表中的函数能够被正确执行(fire中的for循环需要这两个值                             if (firing) {                                 if (index <= firingLength) {                                     firingLength--;                                 }                                 if (index <= firingIndex) {                                     firingIndex--;                                 }                             }                         }                     });                 }                 return this;             },             // Check if a given callback is in the list.             // If no argument is given, return whether or not list has callbacks attached             // 回调函数是否在列表中.             has: function(fn) {                 return fn ? jQuery.inArray(fn, list) > -1 : !! (list && list.length);             },             // Remove all callbacks from the list             // 从列表中删除所有回调函数             empty: function() {                 list = [];                 firingLength = 0;                 return this;             },             // Have the list do nothing anymore             // 禁用回调列表中的回调。             disable: function() {                 list = stack = memory = undefined;                 return this;             },             // Is it disabled?             //  列表中否被禁用             disabled: function() {                 return !list;             },             // Lock the list in its current state             // 锁定列表             lock: function() {                 stack = undefined;                 if (!memory) {                     self.disable();                 }                 return this;             },             // Is it locked?             // 列表是否被锁             locked: function() {                 return !stack;             },             // Call all callbacks with the given context and arguments             // 以给定的上下文和参数调用所有回调函数             fireWith: function(context, args) {                 if (list && (!fired || stack)) {                     args = args || [];                     args = [context, args.slice ? args.slice() : args];                     //如果正在回调                     if (firing) {                         //将参数推入堆栈,等待当前回调结束再调用                         stack.push(args);                     } else { //否则直接调用                         fire(args);                     }                 }                 return this;             },             // Call all the callbacks with the given arguments             // 以给定的参数调用所有回调函数             fire: function() {                 self.fireWith(this, arguments);                 return this;             },             // To know if the callbacks have already been called at least once             // // 回调函数列表是否至少被调用一次             fired: function() {                 return !!fired;             }         };     return self; };

jQuery.Callbacks()的核心思想是 Pub/Sub 模式,建立了程序间的松散耦合和高效通信。

pub/sub (观察者模式) 的背后,总的想法是在应用程序中增强松耦合性。并非是在其它对象的方法上的单个对象调用。一个对象作为特定任务或是另一对象的活动的观察者,并且在这个任务或活动发生时,通知观察者。观察者也被叫作订阅者(Subscriber),它指向被观察的对象,既被观察者(Publisher 或 subject)。当事件发生时,被观察者(Publisher)就会通知观察者(subscriber)。

觉得可用,就经常来吧!Javascript技巧 脚本宝典 欢迎评论哦! js技巧,巧夺天工,精雕玉琢。小宝典献丑了!

本文固定链接: http://www.js-code.com/js/js_1459.html