<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>deferred对象</title>
</head>
<body>
两个对象,一个是promise对象,另一个是deferred对象。
Deferred方法,返回deferred对象。
Deferred里面有then方法,返回promise对象。 jQuery源码
1.对参数做处理。
处理的目的是,对不合法的参数,返回错误。
对不同的参数类型,参数位置,做多态处理。
2.常用&&或者||或者三目判断。
3.常用typeof做判断。
4.假设全部以正确方式来运行的态度,看代码。
5.剔除源代码没必要的遍历,以最小集合来阅读。
</body>
<script src="../jquery-2.0.3.js"></script>
<script>
/*
dfd.then(fn1)
刚开始内部生成一个newDfd,
先把fn1装饰一下变成fn1-1,
再把fn1-1给dfd的函数队列。 因为dfd内部的list是once memory了,
所以fn1-1马上执行,内容如下:
fn1返回fn1-promise,
然后把newDfd的resolve函数给fn1-promise。 dfd.then(fn1)最后返回一个newDfd的newPromise
因为fn1-deferred已经resolve过了,
所以又执行newDfd.resolve,
接下来是下一个then了。
*/
// 看代码,弄清空间和空间之间的运动关系,逻辑也就清晰了。
// 分主次,首先把分枝减掉,留下主干,把主干搞清楚。
function Deferred( func ) {
var list = jQuery.Callbacks("once memory");
var promise = {
then: function() {
var fns = arguments;
var newDfd = Deferred(function( newDefer ) {
var fn = jQuery.isFunction( fns[ 0 ] ) && fns[ 0 ];
deferred[ "done" ](function() {
var returned = fn && fn.apply( this, arguments );
returned.promise().done( newDefer.resolve )
});
fns = null;
});
var newPromise = newDfd.promise();
return newPromise;
},
promise: function( obj ) {
return obj != null ? jQuery.extend( obj, promise ) : promise;
},
done: list.add
},
deferred = {
resolve: function() {
deferred[ "resolveWith" ]( this === deferred ? promise : this, arguments );
return this;
},
resolveWith: list.fireWith,
flag:"newDfd"
}; promise.promise( deferred ); if ( func ) {
func.call( deferred, deferred );
} return deferred;
} var dfd = Deferred();
dfd.flag = "dfdflag";
dfd.then(function(){
var dfd1 = Deferred();
dfd1.flag = "dfd1flag";
alert(1);
dfd1.resolve(); return dfd1.promise();
}).then(function(){
var dfd2 = Deferred();
alert(2);
dfd2.resolve();
return dfd2.promise();
}).then(function(){
var dfd3 = Deferred();
alert(3);
dfd2.resolve();
return dfd2.promise();
}); dfd.resolve(); </script> </html>
其实jQuery的Deferred还是有bug的。
设想如下代码:
function(){
var dfd = $.Deferred();
dfd.resolve();
$.ajax() return dfd.promise();
}
就算你提前resolve,ajax还是会执行。