Promise 有几个 重要的点:
1、promise有三种状态,等待(pending)、已完成(fulfilled)、已拒绝(rejected)
2、promise的状态只能从“等待”转到“完成”或者“拒绝”,不能逆向转换,同时“完成”和“拒绝”也不能相互转换
3、promise必须有一个then方法,而且要返回一个promise,供then的链式调用,也就是可thenable的
4、then接受俩个回调(成功与拒绝),在相应的状态转变时触发,回调可返回promise,等待此promise被resolved后,继续触发then链
一般我们会这么使用Promise:
var promise = new Promise(function(resolve, reject) {
setTimeout(function(){
resolve("val")
})
})
promise.then(onFulfilled,onRejected).then(onFulfilled,onRejected)
我们可以直接对返回的promise对象进行操作,比如then,传入回调,
这里的函数并不会立即执行,而是加入队列,等待未来的某个时间resolve时被触发执行。
实现Promise构造函数
根据Promise实现要点1,定义三个状态
var PENDING = undefined, FULFILLED = 1, REJECTED = 2;
然后实现Promise构造函数,此函数接受一个函数参数,函数参数接受俩个我们提供的方法resolve与reject,供使用者在未来的某个时间里调用触发执行我们的队列
这里还要初始下当前的状态,传递的值,以及then时保存到的队列。
var Promise = function(resolver){
if (!isFunction(resolver))
throw new TypeError("You must pass a resolver function as the first argument to the promise constructor");
if(!(this instanceof Promise)) return new Promise(resolver);
var promise = this;
promise._value;
promise._reason;
promise._status = PENDING;
promise._resolves = [];
promise._rejects = [];
var resolve = function(value){
//状态转换为FULFILLED
//执行then时保存到_resolves里的回调,
//如果回调有返回值,更新当前_value
}
var reject = function(reason){
//状态转换为REJECTED
//执行then时保存到_rejects里的回调,
//如果回调有返回值,更新当前_rejects
}
resolver(resolve,reject);
}
实现then
根据Promise要点3,promise必须有一个then方法,而且要返回一个promise,供then的链式调用
而且promise.then(onFulfilled,onRejected)时,我们要判断当前promise的状态,
如果是pending则把onFulfilled与onRejected添加到_resolves与_rejects数组里,
否则的话根据状态,直接触发回调,这里要注意的是,如果返回的是promise,我们要等到此promise被resolves时,触发then链的下一个promise执行。
var isThenable = function(obj){
return obj && typeof obj["then"] == "function";
}
Promise.prototype.then = function(onFulfilled,onRejected){
var promise = this;
// 每次返回一个promise,保证是可thenable的
return Promise(function(resolve,reject){
function callback(value){
var ret = isFunction(onFulfilled) && onFulfilled(value) || value;
if(isThenable(ret)){
// 根据返回的promise执行的结果,触发下一个promise相应的状态
ret.then(function(value){
resolve(value);
},function(reason){
reject(reason);
});
}else{
resolve(ret);
}
}
function errback(reason){
reason = isFunction(onRejected) && onRejected(reason) || reason;
reject(reason);
}
if(promise._status === PENDING){
promise._resolves.push(callback);
promise._rejects.push(errback);
}else if(promise._status === FULFILLED){ // 状态改变后的then操作,立刻执行
callback(promise._value);
}else if(promise._status === REJECTED){
errback(promise._reason);
}
});
}