Callbacks
Callbacks使用场景在哪里?
在很多时候需要控制一系列的函数顺序执行。那么一般就需要一个队列函数来处理这个问题:
- function Aaron(List, callback) {
- setTimeout(function() {
- var task = List.shift();
- task(); //执行函数
- if (List.length > 0) { //递归分解
- setTimeout(arguments.callee, 1000)
- } else {
- callback()
- }
- }, 25)
- }
- Aaron([function(){
- alert('a')
- },function(){
- alert('b')
- }],function(){
- alert('callback')
- })
- alert(1);
简单实现异步: 依次弹出:1 a b(隔了一秒之后) callback
传入一组函数参数,靠递归解析,分个执行,其实就是靠setTimeout可以把函数加入到队列末尾才执行的原理
jQuery提供的方式:
- 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(); //未执行
我对jquery源码没有特别深入的研究,在此不再详细说jquery内部的实现。之所以对异步感兴趣,是因为在开发中经常会考虑到这些方面的问题,而且比较感兴趣js如何实现异步?其实还是对原生API的使用,包括SetTimeout,setInterval,HTTPRequest,事件监听等。
设计思想:
涉及到了 add 与 fire方法是基于发布订阅的观察者模式的设计了,事件监听也算是js一种内置的发布/订阅模式
pub/sub (观察者模式) 的背后,总的想法是在应用程序中增强松耦合性。并非是在其它对象的方法上的单个对象调用。一个对象作为特定任务或是另一对象的活动的观察者,并且在这个任务或活动发生时,通知观察者。观察者也被叫作订阅者(Subscriber),它指向被观察的对象,既被观察者(Publisher 或 subject)。当事件发生时,被观察者(Publisher)就会通知观察者(subscriber)
作为 $.Callbacks() 的创建组件的一个演示,只使用回调函数列表,就可以实现 Pub/Sub 系统。将 $.Callbacks 作为一个队列
- var Observable = {
- callbacks: [],
- add: function(fn) {
- this.callbacks.push(fn);
- },
- fire: function() {
- this.callbacks.forEach(function(fn) {
- fn();
- })
- }
- }
- Observable.add(function() {
- alert(1)
- })
- Observable.fire(function() {
- alert(2)
- })
- Observable.fire(); // 1, 2