思路大致是这样的,用2个数组(doneList
和failList
)分别存储成功时的回调函数队列和失败时的回调队列
state
: 当前执行状态,有pending
、resolved
、rejected
3种取值done
: 向doneList
中添加一个成功回调函数fail
: 向failList
中添加一个失败回调函数then
: 分别向doneList
和failList
中添加回调函数always
: 添加一个无论成功还是失败都会调用的回调函数resolve
: 将状态更改为resolved
,并触发绑定的所有成功的回调函数reject
: 将状态更改为rejected
,并触发绑定的所有失败的回调函数when
: 参数是多个异步或者延迟函数,返回值是一个Promise兑现,当所有函数都执行成功的时候执行该对象的resolve
方法,反之执行该对象的reject
方法
下面是我的具体实现过程:
var Promise = function() {
this.doneList = [];
this.failList = [];
this.state = 'pending';
};
Promise.prototype = {
constructor: 'Promise',
resolve: function() {
this.state = 'resolved';
var list = this.doneList;
for(var i = 0, len = list.length; i < len; i++) {
list[0].call(this);
list.shift();
}
},
reject: function() {
this.state = 'rejected';
var list = this.failList;
for(var i = 0, len = list.length; i < len; i++){
list[0].call(this);
list.shift();
}
},
done: function(func) {
if(typeof func === 'function') {
this.doneList.push(func);
}
return this;
},
fail: function(func) {
if(typeof func === 'function') {
this.failList.push(func);
}
return this;
},
then: function(doneFn, failFn) {
this.done(doneFn).fail(failFn);
return this;
},
always: function(fn) {
this.done(fn).fail(fn);
return this;
}
};
function when() {
var p = new Promise();
var success = true;
var len = arguments.length;
for(var i = 0; i < len; i++) {
if(!(arguments[i] instanceof Promise)) {
return false;
}
else {
arguments[i].always(function() {
if(this.state != 'resolved'){
success = false;
}
len--;
if(len == 0) {
success ? p.resolve() : p.reject();
}
});
}
}
return p;
}
Improve
目前只是实现了
Promise
的基础功能,但仍然还有无法处理的情况,例如要实现3个或3个以上的异步请求的串行,目前我的Promise
没有办法支持new Promise(A).then(B).then(C)
这样的形式,jQuery
在1.7的版本中为Deferred
(Promise
)对象实现了pipe
函数,可以通过这个函数实现上述功能,代码为$.Deferred(A).pipe(B).then(C)
,我尝试去读了jQuery
这部分的代码,但是没能读懂,希望有大神能够给一些实现思路