function isFunction(fn){
return Object.prototype.toString.call(fn) === '[object Function]';
}
let ST = {
pending: 0,
resolved: 1,
rejected: 2
}
function Promise(fn){
let self = this;
self.status = ST.pending;
self.value = '';
self.reason = '';
self.resolveFns = [];
self.rejectFns = [];
//setTimeout延迟执行,将reslove执行放在下个循环,保证后续then方法先于它执行,不会出现前面已经resolve了,后面的then还没push进resolveFns数组
function resolve(val){
setTimeout(() => {
if(self.status == ST.pending){
self.status = ST.resolved;
self.value = val;
//用数组保存回调,是为了处理一个promise挂载多个then的情况
//注意不是链式,这种场景很少出现
/*
形如:
promise.then(resolve1,reject1)
promise.then(resolve2,reject2)
promise.then(resolve3,reject3)
*/
//在链式调用中,该数组通常只会有一个项,就是当前promise的下一个then里面的resolve函数
//且每次执行,通常都是一个新Promise的resolve数组
self.resolveFns.forEach(fn => fn());
}
})
}
function reject(val){
setTimeout(() => {
if(self.status == ST.pending){
self.status = ST.rejected;
self.reason = val;
self.rejectFns.forEach(fn => fn());
}
})
}
//执行出问题,直接reject,Promise的错误默认不会抛出到全局
try{
fn(resolve,reject);
}
catch(err){
reject(err);
}
}
Promise.prototype.then = function(onResolve,onReject){
let self = this;
//then每次执行都返回一个新的Promise,then方法要处理前一个promise的三种状态
return new Promise(function(resolve,reject){
function handle(value,thenFn){
let res = isFunction(thenFn) && thenFn(value) || value;
if(res instanceof Promise){
res.then(resolve,reject);
}
else{
resolve(res);
}
}
//处理三种状态
//fn函数体里,如果有错误; 会执行try catch里的 reject方法,执行then this.state就是rejected
//如果没错误且没异步,resolve this.state就是resolved
//如果没错误且有异步,this.state就是pending
if(self.status == ST.pending){
self.resolveFns.push(resloveHandle);
self.rejectFns.push(rejectHandle);
}
else if(self.status == ST.resolved){
self.handle(self.value,onResolve);
}
else if(this.status == ST.rejected){
self.handle(self.reason,onReject);
}
})
}
Promise.prototype.catch = function(onReject){
return this.then(undefined, onReject);
}
//finally不是promise的末尾,后面还可以有then,所以value和reason必须可以向下传递
Promise.prototype.finally = function(fn){
let P = this.constructor;
return this.then(
value => P.resolve(fn()).then(() => value),
reason => P.resolve(fn()).then(() => throw reason);
)
}
//done作为promise的末尾,用于收集所有可能的报错,catch方法捕捉所有错误,并抛出
Promise.prototype.done = function(resolve,reject){
return this.then(resolve, reject).catch(function(reason){
setTimeout(function(){
throw reason;
});
})
}
Promise.resolve = function(val){
return new Promise((resolve) => {
resolve(val);
})
}
Promise.reject = function(val){
return new Promise((resolve,reject) => {
reject(val);
})
}
Promise.race = function(promises){
let len = promises.length;
return new Promise(function(resolve,reject){
while(len--){
promises[len].then(resolve,reject);
}
})
}
Promise.all = function(promises){
let len = promises.length,
results = [];
return new Promise(function(resolve,reject){
//用一个数组收集单个promise执行后的结果,收集满数组所有结果,便是所有执行成功
function reslove(index){
return function(value){
results[index] = value;
if(results.length == len){
reslove(results);
}
}
}
while(len--){
promises[len].then(resolve(len),reject);
}
})
}