这是一个管理事件的工具:异步队列,
小编在jQ代码中搜索了一下,发现在ajax的代码中有应用。您可以在阅读代码时想象下,在ajax场景的应用
下面我们来看下整体代码结构:
var Deferred = function( func ) {
//使用Callbacks()进行对事件的管理:
//memory模式,fire后再添加的事件将直接被触发
//once模式,触发过的事件讲不会再被触发
var doneList = jQuery.Callbacks( "once memory" ),
failList = jQuery.Callbacks( "once memory" ),
progressList = jQuery.Callbacks( "memory" ),
//初始化的状态描述:等待
state = "pending",
//这个对象变量下面有应用 resolve:解决, reject:拒绝, notify:通知
lists = {
resolve: doneList,
reject: failList,
notify: progressList
},
promise = {
//保存各自的添加事件的方法
done: doneList.add,
fail: failList.add,
progress: progressList.add,
//批量添加
then: function( doneCallbacks, failCallbacks, progressCallbacks ) {
deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks );
return this;
},
//同步添加到done/fail队列
always: function() {
deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments );
return this;
},
//获取当前状态的描述
state: function() {
return state;
},
isResolved: doneList.fired,
isRejected: failList.fired,
pipe: function( fnDone, fnFail, fnProgress ) {
//...
},
// 复制自身 如果传入的是一个对象,则将promise对象复制一份返回
promise: function( obj ) {
if ( obj == null ) {
obj = promise;
} else {
for ( var key in promise ) {
obj[ key ] = promise[ key ];
}
}
return obj;
}
},
//返回一个对象副本
deferred = promise.promise({}),
key;
// { resolve: doneList.fire, reject: failList.fire, notify: progressList.fire }
// 就是对应各自列表的fire,fireWith函数
for ( key in lists ) {
deferred[ key ] = lists[ key ].fire;
deferred[ key + "With" ] = lists[ key ].fireWith;
}
/*
这里小编稍微解释下,在此三个列表中,done表示的是事件成功时执行的列表,
fail表示的是事件失败时执行的列表【可以想象ajax】
这里系统级的对两个事件列表添加3个事件:更改状态描述,禁用对立的列表,锁定消息列表
这里出现了连锁操作,回到之前的callback文中,代码中,我们看到 self.add 函数内部尾部返回了this
那对于这里来说呢this指向的就是deferred对象,所以出现了 .done().fail();
*/
deferred.done( function() {
state = "resolved";
}, failList.disable, progressList.lock ).fail( function() {
state = "rejected";
}, doneList.disable, progressList.lock );
// 对于传入的函数进行调用,这里小编下一张在进行介绍
if ( func ) {
func.call( deferred, deferred );
}
return deferred;
}
小编在稍微解释下promise里的几个api:
done, fail, progress, then, always 这5个api都是用来添加事件到相应的队列
done, fail, progress 这3个单个添加到各自的队列
then 可以一次指定1-3个事件添加到各自的队列中
always 可以将传入的所有事件同时添加到成功和失败队列中
最后,小编来举个极其简单的操作的例子..
var def = new Deferred();
//添加一个事件
def.done(function(data){
console.log( '>>>', data );
});
//进行一些异步逻辑后进行了事件触发 def.resolve({'a':1,'b':2});