//申明常量 promise的3个基本状态
const SUCCESS = 'fulfilled';
const FAIL = 'rejected';
const PENDING = 'pending';
//返回的那个新的promise x是then方法中的返回值
function resolvePromise(promise2,x,resolve,reject){
if(promise2 === x){
reject(new TypeError('TypeError: Chaining cycle detected for promise #<Promise>'));
}
let called;
//判断x的类型
//promise 有n种实现方式 都符合这个规范 兼容别人的 promise
//怎么判断 x是不是一个 promise 看他有没有then方法
if(typeof x === 'function' || (typeof x === 'object' && x != null)){
try{
let then = x.then; //取then可能会报错
if(typeof then === 'function'){
then.call(x,y=>{ //如果promise是成功的就把结果往下传,如果失败的就让下一个人也失败
if(called) return; //1)//为了辨别这个promise不能多次调用
called = true;
resolvePromise(promise2,y,resolve,reject)
},r=>{
if(called) return; //2)//为了辨别这个promise不能多次调用
called = true;
reject(r)
}) //避免取多次 不要使用x.then() 否则会再次取值
}else{
resolve(x)
}
}catch(e){
if(called) return; //3)//为了辨别这个promise不能多次调用
called = true;
reject(e)
}
}else{
resolve(x) // 只要是一个普通值就需要接着往下面抛
}
}
class Promise{
constructor(executor){ //executor 执行器 只要new Promise()的时候就会执行
this.status = PENDING; //默认状态为等待态
this.value = undefined; //then 回调成功的返回值
this.reason = undefined; //then 回调失败的返回值
this.onResolveCallbacks = []; //成功所有的回调 只有pending的时候才存储
this.onRejectedCallbacks = []; //失败所有的回调 只有pending的时候才存储
let resolve = (value)=>{ //成功回调函数 改变状态并保存返回值
if(value instanceof Promise){ //如果resolve的结果是一个promise
return value.then(resolve,reject) //那么会让这个promise执行,将执行后的结果再传递给 resolve或者reject中
}
if(this.status === PENDING){ //只有在等待态的时候才能改变状态
this.value = value;
this.status = SUCCESS;
this.onResolveCallbacks.forEach(fn => fn())
}
}
let reject = (reason)=>{ //失败回调函数 改变状态并保存返回值
if(this.status === PENDING){ //只有在等待态的时候才能改变状态
this.reason = reason;
this.status = FAIL;
this.onRejectedCallbacks.forEach(fn => fn())
}
}
try{ //在new Promise的时候可能内部会抛错误,所以需要try catch
executor(resolve,reject); //只要new Promise()的时候就会执行 并且可传递两个回调函数 成功、失败
}catch(e){
reject(e);
}
}
then(onFulfilled,onRejected){ //根据状态执行不同的函数
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val;
onRejected = typeof onRejected === 'function' ? onRejected : err => {throw err};
let promise2;
//可以不停的调用then方法,返回了一个新的promise
promise2 = new Promise((resolve,reject)=>{
if(this.status === SUCCESS){
setTimeout(()=>{ //定时器解决调用resolvePromise的时候promise2为undefined
try{ //执行的时候抛出错误,需要try catch 捕获
//调用当前then方法的结果,来判断当前这个promise2是成功还是失败
let x = onFulfilled(this.value)
//这里的x是普通值还是promise
//如果这个是promise呢?
resolvePromise(promise2,x,resolve,reject)
}catch(err){
reject(err)
}
})
}
if(this.status === FAIL){
setTimeout(()=>{
try{
let x = onRejected(this.reason);
resolvePromise(promise2,x,resolve,reject)
}catch(err){
reject(err)
}
})
}
if(this.status === PENDING){ //多次调用并且pending的时候存储函数
this.onResolveCallbacks.push(()=>{
setTimeout(()=>{
try{
let x = onFulfilled(this.value)
resolvePromise(promise2,x,resolve,reject)
}catch(err){
reject(err)
}
})
})
this.onRejectedCallbacks.push(()=>{
setTimeout(()=>{
try{
let x = onRejected(this.reason);
resolvePromise(promise2,x,resolve,reject)
}catch(err){
reject(err)
}
})
})
}
})
return promise2;
}
catch(errCallback){ //用来捕获错误
return this.then(null,errCallback)
}
}
//希望测试一下这个库是否符合promise A+规范
//promises-aplus-tests
Promise.defer = Promise.deferred = function(){
let dfd = {};
dfd.promise = new Promise((resolve,reject)=>{
dfd.resolve = resolve;
dfd.reject = reject;
});
return dfd;
}
module.exports = Promise;
网友评论