手写Promise代码,供参考
const PENDING = "PENDING";
const FULFILLED = "FULLFILLED";
const REJECTED = "REJECTED";
class MyPromise{
constructor(fn){
this.state = PENDING;
this.value = undefined;
this.onFulfilledHandlers = [];
this.onRejectedHandlers = [];
try {
fn(this._resolve.bind(this), this._reject.bind(this))
} catch (error) {
this._reject(error)
}
}
_resolve(value){
if(this.state !== PENDING) return
this._changestate(FULFILLED,value)
while(this.onFulfilledHandlers.length){
this.onFulfilledHandlers.shift()(this.value)
}
}
_reject(error){
if(this.state !== PENDING) return
this._changestate(REJECTED,error)
while(this.onRejectedHandlers.length){
this.onRejectedHandlers.shift()(this.value)
}
}
_changestate(state_, value){
this.state = state_;
this.value = value;
}
then(onFulfilled, onRejected){
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : error => {throw error};
const thenPromise = new MyPromise((resolve, reject) =>{
if(this.state === FULFILLED){
try {
queueMicrotask(() => {
const resolveRes = onFulfilled(this.value);
handlePromise(resolveRes, thenPromise, resolve, reject);
})
} catch (error) {
reject(error);
}
} else if (this.state === REJECTED){
try {
queueMicrotask(() => {
const rejectRes = onRejected(this.value);
handlePromise(rejectRes, thenPromise, resolve, reject);
})
} catch (error) {
reject(error);
}
} else{
this.onFulfilledHandlers.push(() => {
try {
let fulfilledRes = onFulfilled(this.value)
handlePromise(fulfilledRes, thenPromise,resolve, reject)
} catch (error) {
reject(error)
}
})
this.onRejectedHandlers.push(() => {
try {
let rejectRes = onRejected(this.value)
handlePromise(rejectRes, thenPromise,resolve, reject)
} catch (error) {
reject(error)
}
})
}
})
return thenPromise
}
}
function handlePromise(promiseres, thenpromise, resolve, reject){
if(promiseres === thenpromise){
throw new Error("can not be self")
}
if(promiseres instanceof MyPromise){
promiseres.then(resolve, reject)
} else {
resolve(promiseres)
}
}
const promise = new MyPromise((resolve) => {
setTimeout(() => {
resolve(1000)
}, 1000)
})
promise.then(res => {
console.log(res)
}).then(res => {
console.log(res)
return new MyPromise(resolve => resolve(3000))
}).then(res => {
console.log(res);
})