基础版本实现:
- then函数实现成功和失败函数的同步注册
- resolve和reject函数实现成功和失败函数的异步执行,并改变当前promsie的状态
class PromiseA {
constructor(fn) {
this.status = PENDING;//状态
this.value = undefined;
this.error = undefined;
this.onFulfilled = undefined;//成功处理函数
this.onRejected = undefined;//失败处理函数
fn(this.resolve.bind(this), this.reject.bind(this));
}
resolve(value) {
if (this.status === PENDING) {
setTimeout(() => {//保证为异步执行
this.status = FULFILLED;//改变状态
this.value = value;
this.onFulfilled(this.value);
}, 0)
}
}
reject(error) {
if (this.status === PENDING) {
setTimeout(() => {//保证为异步执行
this.status = REJECTED;//改变状态
this.error = error;
this.onRejected(this.error);
}, 0)
}
}
then(onFulfilled, onRejected) {
//判断onFulfilled/onRejected是否是函数,给默认函数
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : error => { throw error };
if (this.status === PENDING) {
//如果状态是PENDING,将回调函数缓存,以供resolve/reject调用
this.onFulfilled = onFulfilled;
this.onRejected = onRejected;
} else if (this.status === FULFILLED) {
//如果状态是fulfilled,直接执行成功回调,并将成功值传入
onFulfilled(this.value)
} else {
//如果状态是rejected,直接执行失败回调,并将失败原因传入
onRejected(this.error)
}
return this;
}
catch(onRejected) {
return this.then(null, onRejected);
}
}
完整版本实现:
1.根据Promises/A+规范,then函数每次都返回一个promise对象,详情如下:
function resolvePromise(bridgePromise, x, resolve, reject) {
if (x === bridgePromise) {
return reject(new TypeError('循环引用'))
}
let called = false; // 避免多次调用
if (x instanceof PromiseB) {//promise对象
if (x.status === PENDING) {
x.then(y => {
resolvePromise(bridgePromise, y, resolve, reject)
}, e => {
reject(e)
})
} else {
x.then(resolve, reject)
}
} else if (x && ((typeof x === 'object') || (typeof x === 'function'))) {
try {
// 是否是thenable对象(具有then方法的对象/函数)
let then = x.then;
if (typeof then === 'function') {
//如果 then 是一个函数,以x为this调用then函数,且第一个参数是resolvePromise,第二个参数是rejectPromise
then.call(x, y => {
if (called) return;
called = true;
resolvePromise(bridgePromise, y, resolve, reject);
}, e => {
if (called) return;
called = true;
reject(e);
})
} else { // 说明是一个普通对象/函数
resolve(x)
}
} catch (e) {
if (called) return;
called = true;
reject(e);
}
}
else {
resolve(x)
}
}
function gen(length, resolve) {
let values = [],
count = 0;
return function (value, i) {
values[i] = value;
if (++count === length) {
resolve(values)
}
}
}
class PromiseB {
constructor(fn) {
this.status = PENDING;
this.value = undefined;
this.error = undefined;
this.onFulfilledCallbacks = [];//成功回调函数队列
this.onRejectedCallbacks = [];//失败回调函数队列
fn(this.resolve.bind(this), this.reject.bind(this))
}
static resolve(value) {
return new PromiseB((resolve, reject) => {
resolve(value);
});
}
static reject(error) {
return new PromiseB((resolve, reject) => {
reject(error);
});
}
static race(promises) {
/**
* Promise.race
* 参数: 接收 promise对象组成的数组作为参数
* 返回值: 返回一个Promise实例
* 只要有一个promise对象进入 FulFilled 或者 Rejected 状态的话,就会继续进行后面的处理(取决于哪一个更快)
*/
return new PromiseB((resolve, reject) => {
promises.forEach((promise, index) => {
promise.then(resolve, reject);
});
});
}
static all(promises) {
/**
* Promise.all Promise进行并行处理
* 参数: promise对象组成的数组作为参数
* 返回值: 返回一个Promise实例
* 当这个数组里的所有promise对象全部变为resolve状态的时候,才会resolve。
*/
return new PromiseB((resolve, reject) => {
let done = gen(promises.length, resolve);
promises.forEach((promise, index) => {
promise.then((value) => {
done(index, value);//每次调用,会计算gen中缓存count,全部完成返回此时的数组value
}, reject)
})
})
}
resolve(value) {
if (this.status === PENDING) {
setTimeout(() => {
this.status = FULFILLED;
this.value = value;
this.onFulfilledCallbacks.forEach((callback) => {
callback(this.value)
})
});
}
}
reject(error) {
if (this.status === PENDING) {
setTimeout(() => {
this.status = FULFILLED;
this.error = error;
this.onFulfilledCallbacks.forEach((callback) => {
callback(this.error)
})
});
}
}
then(onFulfilled, onRejected) {
let bridgePromise;
//处理onFulfilled/onRejected 不存在情况
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : error => { throw error };
if (this.status === PENDING) {//等待状态
return bridgePromise = new PromiseB((resolve, reject) => {
this.onFulfilledCallbacks.push((value) => {
try {
let x = onFulfilled(value);//执行then中成功回调,value将在resolve中传入
resolvePromise(bridgePromise, x, resolve, reject);//解析x
} catch (e) {
reject(e)
}
})
this.onRejectedCallbacks.push((error) => {
try {
let x = onRejected(error);//执行then中错误回调,error将在reject中传入
resolvePromise(bridgePromise, x, resolve, reject);//解析x
} catch (e) {
reject(e)
}
})
})
}
if (this.status === FULFILLED) {//成功状态
return bridgePromise = new PromiseB((resolve, reject) => {
setTimeout(() => {//确保为异步执行
try {
let x = onFulfilled(this.value);
resolvePromise(bridgePromise, x, resolve, reject);
} catch (e) {
reject(e)
}
});
})
}
if (this.status === REJECTED) {//失败状态
return bridgePromise = new PromiseB((resolve, reject) => {
setTimeout(() => {
try {
let x = onRejected(this.error);
resolvePromise(bridgePromise, x, resolve, reject);
} catch (e) {
reject(e)
}
});
})
}
}
catch(onRejected) {
return this.then(null, onRejected);
}
}