jQuery的deferred对象详解(二)
Deferred对象是由$.Deferred构造的,$.Deferred被实现为简单的工厂模式。
$.Deferred的实现
- 创建三个$.Callbacks对象,分别表示成功done,失败fail,处理中process三种状态
- 对应了三种处理结果,resolve、reject、notify
- 创建了一个promise对象,具有state、always、then、primise方法
- 通过扩展primise对象生成最终的Deferred对象,是阻止其他代码来改变这个deferred对象的状态,deferred.promise() 改变不了 deferred 对象的状态,作用也不是保证目前的状态不变
上面提到Deferred里面的3个$.Callback()的实例,Deferred自身则围绕这三个对象进行更高层次的抽象。以下是Deferred对象的核心方法
1.done/fail/progress是callbacks.add,将回调函数增加到回调管理器
2.resolve/reject/notify是callback.fire,执行回调函数(或队列)
$.Deferred成员的方法
1.$.Deferred()
生成一个异步队列实例对象deferred
接受一个function参数,function里边可以使用this来调用当前的异步队列实例
2.deferred.done(fn)
成功时触发的回调fn
3.deferred.fail(fn)
失败时触发的回调
4.deferred.progress(fn)
处理中触发的回调
5.deferred.resolve/resolveWith([context],args)
这里等同$.Callbacks().(fire/fireWith)
在任务处理成功之后使用此方法触发成功事件,之前加入done队列的回调会被触发
6.deferred.reject/rejectWith([context],args)
这里等同$.Callbacks().(fire/fireWith)
在任务处理成功之后使用此方法触发成功事件,之前加入fail队列的回调会被触发
7.deferred.notify/notifyWith([context],args)
这里等同$.Callbacks().(fire/fireWith)
在任务处理中可以使用此方法触发正在处理的事件
8.deferred.promise()
deferred.promise() 只是阻止其他代码来改变这个 deferred 对象的状态,通过 deferred.promise() 方法返回的 deferred 对象,是没有 resolve ,reject, progress , resolveWith, rejectWith , progressWith 这些可以改变状态的方法
9.deferred.then([fnDone,fnFail,fnProgress])
可以直接传入三个回调函数,分别对应done|fail|progress三个状态的回调,例$.when($.ajax("/main.php")).then(successFunc,failureFunc,proFunc),第一个参数是done()方法的回调函数,第二个参数是fail方法的回调函数,第三个是progress的回调函数,也可以只传一个参数,则是done()方法的回调函数
10.deferred.always(fn)
不管最后是resolve还是reject,都会触发fn
11.$.when(mission1,[mission2,mission3,...])
这个事挂载在jQuery上的方法, 为多个操作指定回调函数,例$.when($.ajax("test1.html",$.ajax("test2.html"))).done(fn).fail(fn)
$.Deferred源码结构
// Deferred 委托人对象,对委托人管理 jQuery.extend({ Deferred: function (func) { var tuples = [ // action 执行状态, add listener 添加侦听器(事件处理函数),listener list 侦听器列表(事件处理函数列表),final state 最终状态 ["resolve", "done", jQuery.Callbacks("once memory"), "resolved"], ["reject", "fail", jQuery.Callbacks("once memory"), "rejected"], ["notify", "progress", jQuery.Callbacks("memory")] ], promise = { state: function () { return state; }, always: function () { deferred.done(arguments).fail(arguments); return this; }, then: function ( /* fnDone, fnFail, fnProgress */) { // 声明一个变量,并把参数引用赋值给funs var fns = arguments; // newDefer 创建一个新的委托人 return jQuery.Deferred(function (newDefer) { jQuery.each(tuples, function (i, tuple) { }); // 清空变量,内存回收 fns = null; }).promise();//返回一个受到限制的委托人 }, promise: function (obj) { return obj != null ? jQuery.extend(obj, promise) : promise; } }, // 声明变量 创建一个委托人 deferred = {}; // 添加一个方法名pipe与then相同,一般使用pipe进行filter操作 promise.pipe = promise.then; jQuery.each(tuples, function (i, tuple) { //声明一个局部变量,将观察器对象引用给list var list = tuple[2], stateString = tuple[3]; //委托人的最终状态 promise[tuple[1]] = list.add; // 将委托人的通知和观察者对象的执行回调函数(观察者函数) 联系起来 deferred[tuple[0]] = function () { deferred[tuple[0] + "With"](this === deferred ? promise : this, arguments); return this; }; deferred[tuple[0] + "With"] = list.fireWith; }); // 为委托人添加一个被限制的委托人对象 (将promise对象extend到deferred中) promise.promise(deferred); // 检测func是否存在,存在将生成的委托人对象作为这个函数的默认参数,以及将this指向这个委托人 if (func) { func.call(deferred, deferred); } // 返回委托人对象 return deferred; }, when: function (subordinate /* , ..., subordinateN */) { var i = 0, resolveValues = core_slice.call(arguments), progressValues, progressContexts, resolveContexts; if (!remaining) { deferred.resolveWith(resolveContexts, resolveValues); } return deferred.promise(); } });
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。