class MyPromise {
constructor(handle) {
this._state = 'PENDING';
this._result = null;
this._fulfilledCbs = [];
this._rejectedCbs = [];
try {
handle(this.resolve, this.reject);
} catch (ex) {
this.reject(ex);
}
}
resolve = (res) => {
if (this._state !== 'PENDING') return;
this._state = 'FULFILLED';
this._result = res;
setTimeout(() => {
this._fulfilledCbs.forEach(fulfilledCb => {
fulfilledCb(res);
})
})
}
reject = (res) => {
if (this._state !== 'PENDING') return;
this._state = 'REJECTED';
this._result = res;
setTimeout(() => {
this._rejectedCbs.forEach(rejectedCb => {
rejectedCb(res);
})
})
}
then = (fulfilledCb, rejectedCb) => {
const { _state, _result } = this;
return new MyPromise((fulfillNext, rejectNext) => {
const fulfill = (res) => {
try {
if (!isFunction(fulfilledCb)) {
fulfillNext(res);
} else {
const fulfilledResult = fulfilledCb(res);
if (fulfilledResult instanceof MyPromise) {
fulfilledResult.then(fulfillNext, rejectNext);
} else {
fulfillNext(fulfilledResult);
}
}
} catch (er) {
rejectNext(er)
}
}
const reject = (res) => {
try {
if (!isFunction(rejectedCb)) {
rejectNext(res);
} else {
const rejectedResult = rejectedCb(res);
if (rejectedResult instanceof MyPromise) {
rejectedResult.then(fulfillNext, rejectNext);
} else {
fulfillNext(fulfilledResult);
}
}
} catch (er) {
rejectNext(er)
}
}
const stateMap = {
'PENDING': () => {
this._fulfilledCbs.push(fulfill);
this._rejectedCbs.push(reject);
},
'FULFILLED': () => {
fulfill(_result);
},
'REJECTED': () => {
reject(_result);
}
}
stateMap[_state]();
// switch (_state) {
// // 当状态为pending时,将then方法回调函数加入执行队列等待执行
// case 'PENDING':
// this._fulfilledCbs.push(fulfill)
// this._rejectedCbs.push(reject)
// break
// // 当状态已经改变时,立即执行对应的回调函数
// case 'FULFILLED':
// fulfill(_result);
// break
// case 'REJECTED':
// reject(_result);
// break
// }
})
}
static all(proms) {
return new MyPromise((resolve, reject) => {
let resArr = [];
let count = 0;
proms.forEach((prom) => {
if (prom instanceof MyPromise) {
prom.then(res => {
resArr.push(res);
++count === proms.length && resolve(resArr);
}, (err) => {
reject(err)
});
} else {
resArr.push(prom);
}
})
})
}
}
isFunction = (obj) => {
return typeof obj === 'function';
}
const prom = new MyPromise((resolve, reject) => {
setTimeout(() => { resolve(1); });
});
prom.then((res) => {
console.log(res);
});
prom.then((res) => {
console.log(2, res);
return 'x';
}).then((res) => {
console.log(22, res);
});
let p1 = new MyPromise((resolve) => resolve(1)),
p2 = new MyPromise((resolve) => resolve(2)),
p3 = new MyPromise((resolve) => resolve(3));
MyPromise.all([p1, p2, p3]).then((res) => {
console.log(res, 'res')
}, (err) => {
console.log(err, 'err')
})
// [1, 2, 3]
let p11 = new MyPromise((_, reject) => reject(1)),
p21 = new MyPromise((resolve) => resolve(2)),
p31 = new MyPromise((resolve) => resolve(3));
MyPromise.all([p11, p21, p31]).then((res) => {
console.log(res, 'res')
}, (err) => {
console.log(err, 'err')
})
// 1 "err"