对外暴露3个实例方法 then、catch、finally
7个静态方法 resolve、reject、all、race、allSetteled、any、try。
采用宏任务方式实现(setTimeout)
核心难点在 then 方法的实现
export default class MockPromise {
_state = 'pending';
_value;
_callBack = [];
constructor(fn) {
let resolve = (value) => {
this._doResolve('fulfilled', value)
}
let reject = (error) => {
this._doResolve('rejected', error)
}
fn(resolve, reject)
}
_doResolve(state, value) {
if (this._state !== 'pending') {
return
}
this._state = state;
this._value = value;
setTimeout(() => {
if (this._state === 'fulfilled') {
this._callBack.forEach(({onFulfilled}) => {
onFulfilled && onFulfilled(this._value)
})
}
if (this._state === 'rejected') {
this._callBack.forEach(({onRejected}) => {
onRejected && onRejected(this._value)
})
}
}, 0)
}
then(fulfilledHandler, rejectedHandler) {
return new MockPromise((resolve, reject) => {
this._callBack.push({
onFulfilled: value => {
let result = fulfilledHandler ? fulfilledHandler(value) : this._value;
if (result instanceof MockPromise) {
result.then(
newValue => {
resolve(newValue)
},
newError => {
reject(newError)
})
} else {
resolve(result)
}
},
onRejected: error => {
let result = rejectedHandler ? rejectedHandler(error) : this._value;
if (result instanceof MockPromise) {
result.then(
newValue => {
resolve(newValue)
},
newError => {
reject(newError)
})
} else {
reject(result)
}
}
})
})
}
catch(rejectedHandler) {
return this.then(null, rejectedHandler)
}
finally(finalHandler) {
return this.then(
(value) => {
finalHandler();
return value
},
(error) => {
finalHandler();
return error
}
)
}
static resolve(value) {
return new MockPromise(resolve => {
resolve(value)
})
}
static reject(error) {
return new MockPromise((resolve, reject) => {
reject(error)
})
}
static all(arr) {
return new MockPromise((resolve, reject) => {
let result = [];
let i = 0;
for (let p of arr) {
let len = arr.length;
p = p instanceof MockPromise ? p : MockPromise.resolve(p);
p.then(value => {
result[i++] = value;
if (result.length === len) {
resolve(result)
}
}).catch(error => {
reject(error)
})
}
})
}
static race(arr) {
return new MockPromise((resolve, reject) => {
for (let p of arr) {
p = p instanceof MockPromise ? p : MockPromise.resolve(p);
p.then(value => {
resolve(value)
}).catch(error => {
reject(error)
})
}
})
}
static allSettled(arr) {
return new MockPromise((resolve, reject) => {
let result = [];
let i = 0;
for (let p of arr) {
let len = arr.length;
p = p instanceof MockPromise ? p : MockPromise.resolve(p);
p.then(value => {
result[i++] = {status: 'fulfilled', value: value};
if (result.length === len) {
resolve(result)
}
}).catch(error => {
result[i++] = {status: 'rejected', reason: error};
if (result.length === len) {
reject(result)
}
})
}
})
}
static any(arr) {
return new MockPromise((resolve, reject) => {
let result = [];
let i = 0;
for (let p of arr) {
let len = arr.length;
p = p instanceof MockPromise ? p : MockPromise.resolve(p);
p.then(value => {
resolve(value)
}).catch(error => {
result[i++] = new Error(error);
if (result.length === len) {
reject(result)
}
})
}
})
}
static try(fn) {
return new MockPromise( (resolve) => {
resolve(fn())
})
}
}
网友评论