解读JSDeferred源码2
继续第一部分最后的例子:
Deferred.define();
//同步处理
next(function func1(){
alert("a1")
})
.next(function func2(){
alert("a2")
})
//异步处理
next(function func1(){
alert("b1")
})
.wait(0) // ←注意这里
.next(function func2(){
alert("b2")
})
//依次alerts b1 a1 a2 b2
第一部分就提到,如果光是调用next,只有第一个next是异步,其他是同步执行。而多了一个wait就不一样了, 看到没有,完全打乱了执行顺序。首先我们先找到wait函数吧。
我们是其原型链中是找不到wait函数的,但找到一个同名的静态方法:
Deferred.register = function (name, fun) {
this.prototype[name] = function () {
return this.next(Deferred.wrap(fun).apply(null, arguments));
};
};
Deferred.wrap = function (dfun) {
return function () { // ←この関数を便宜的に A と呼ぶことにするよ
var a = arguments;
return function () {
return dfun.apply(null, a);
};
};
};
Deferred.register("loop", Deferred.loop);
Deferred.register("wait", Deferred.wait);
Deferred.register的作用是把相关的静态方法变成实例方法。在最新的版本中,wrap已经整合到register中:
Deferred.register = function (name, fun) {
this.prototype[name] = function () {
var a = arguments;
return this.next(function () {
return fun.apply(this, a);
});
};
};
Deferred.register("loop", Deferred.loop);
Deferred.register("wait", Deferred.wait);
我们知道实例方法next会创建一个新实例,并修正其callback.ok。而这里相当于把其callback.ok设为function () {return fun.apply(this, a); }。 这是一个curry,需要补全参数,结合我们的例子,它将为0,而fun则实质为Deferred.wart。换言之,callback.ok的值实质为 function (n) {return eferred.wait(n); }。为方便起见,我们把这次创建的实例称之为,d_implicit,其对应回调函数为implicit。
好了,我们再回到_fire函数。
_fire : function (okng, value) {
var next = "ok";
try {
value = this.callback[okng].call(this, value);
} catch (e) {
next = "ng";
value = e;
if (Deferred.onerror) Deferred.onerror(e);
}
if (value instanceof Deferred) {
value._next = this._next;
} else {
if (this._next) this._next._fire(next, value);
}
return this;
}
在try_catch中,我们执行implicit,从而调用Deferred.wait,而Deferred.wait会产生一个新的实例d_wait, 然后在value instanceof Deferred分支中将其_next设为d_implicit._next(d2)。然后等,等wait中的setTimeout函数执行。 setTimeout里面是一个实例函数call,调用者为d_wait。call会再次调用_fire,并且由于d_wait的回调函数为function(s){return x} 因此,会再次调用_fire,让其_next执行其callback。
整个构思实在惊为天人啊!
next(function func1(){
//创建一个Deferred实例d1,
//callback.ok = func1,_next = d_implicit(见下★)
alert("b1")
})
.wait(0)
//next->post 创建一个 Deferred实例d_implicit ★
//callback.ok = function implicit(a) {return fun.apply(this, a); }
//callback.ok = function implicit(a) {return Deferred.wait(a); }
//_next = d2(见下★★)
.next(function func2(){
//next->post 创建一个 Deferred实例d2 ★★
//callback.ok = func2
//_next = new Deferred
alert("b2")
})
//上面是静态部分
//下面动态部分,
//d1调用func2,返回undefined,因此执行
//d_implicit调用function implicit(a) {return Deferred.wait(a); }
//其间产生d_wait实例,callback_ok为function(x){return x},_next = new Deferred
//但在_fire中的if(value instanceof Deferred)中,重置d_wait的_next为d_implicit.next,
//即d_wait的_next为d2
//wait中的setTimeout会执行d_wait.call(n),call再调用_fire
//d_wait调用function (x) {return x; },由于非Deferred实例,因此再次调用_fire
//让其_next执行其callback,而_next即为d2
| d1 | 静态next创建 | |
| callback | func1 | |
| _next | d_implicit | |
| d_implicit | 实例wait创建(wait->next->_post) | |
| callback | function implicit(a) {return Deferred.wait(a); } | |
| _next | d2 | |
| d2 | 实例next创建(next->_post) | |
| callback | func2 | |
| _next | null | |
| d_wait | 静态wait创建 | |
| callback | function(x){return x} | |
| _next | d_implicit._next |
执行过程为:
//d1 setTimeout d_implicit d_wait setTimeout d2
浙公网安备 33010602011771号