之前看别人公众号里面的面试题有问道promise的实现,看到之后一脸懵,也搜了一下看看别人对promise是怎么实现的,这里也记录一下在看别人的还有自己思考的一些
最简单的实现一部分功能
class myPromise {
constructor(executor) {
this.__resolveQueue = [];
this.__rejectQueue = [];
const resolve = val => {
while(this.__resolveQueue.length) {
const fn = this.__resolveQueue.shift();
fn(val);
}
}
const reject = val => {
while(this.__rejectQueue.length) {
const fn = this.__rejectQueue.shift();
fn(val);
}
}
executor(resolve, reject);
}
then(resolveFn, rejectFn) {
this.__resolveQueue.push(resolveFn);
this.__rejectQueue.push(rejectFn);
}
}
加上状态
promise运行有三个状态:
- pending:初始状态,不是成功也不是失败
- fulfilled: 意味着操作成功完成
- rejected: 意味着操作失败
它的状态只能是pending -> fulfilled或者pending -> rejected,无法逆转这也就是说,后面要做链式的时候其实是一个新的promise
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class myPromise {
constructor(executor) {
this.__resolveQueue = [];
this.__rejectQueue = [];
this.__status = PENDING;
const resolve = val => {
if (this.__status !== PENDING) return;
this.__status = FULFILLED;
while(this.__resolveQueue.length) {
const fn = this.__resolveQueue.shift();
fn(val);
}
}
const reject = val => {
if (this.__status !== PENDING) return;
this.__status = FULFILLED;
while(this.__rejectQueue.length) {
const fn = this.__rejectQueue.shift();
fn(val);
}
}
executor(resolve, reject);
}
then(resolveFn, rejectFn) {
this.__resolveQueue.push(resolveFn);
this.__rejectQueue.push(rejectFn);
}
}
实现带链式then的
上面也说了,因为状态是单向的,不可逆的,但是在操作then的时候,可能本来是fulfilled,但是下一个就是rejected得了,所以它每一个的then都是一个新的promise,也就是说需要在then里面返回一个promise
then(resolveFn, rejectFn) {
return new myPromise((resolve, reject) => {
const fulfilledFn = val => {
try {
// 上一个then的返回值,作为下一个resolve的实参
reject(resolveFn(val));
} catch (error) {
reject(error)
}
}
const rejectedFn = val => {
try {
reject(rejectFn(val));
} catch (error) {
reject(error);
}
}
this.__resolveQueue.push(fulfilledFn);
this.__rejectQueue.push(rejectedFn);
});
}
同时,then里面也还是可以放promise的,我们把原始的promise叫做A,这个被return的promise叫做B,那么B后面所有的then都应该是B这个promise的相关方法
promise.then(res => {
return new myPromise((resolve, reject) => {
...
})
})
这个时候也就需要在then方法里面判断一次,看接收到的返回值是promise还是其他的
then(resolveFn, rejectFn) {
return new myPromise((resolve, reject) => {
const fulfilledFn = val => {
try {
const returnVal = resolveFn(val);
returnVal instanceof myPromise ? returnValue.then(resolve, reject) : resolve(returnValue);
} catch (error) {
reject(error)
}
}
const rejectedFn = val => {
try {
const returnVal = resolveFn(val);
// 这里使用resolve是因为catch的后一个then,默认是resolve
returnVal instanceof myPromise ? returnValue.then(resolve, reject) : resolve(returnValue);
} catch (error) {
reject(error);
}
}
this.__resolveQueue.push(fulfilledFn);
this.__rejectQueue.push(rejectedFn);
});
}