实现promise以及promise.all
这篇文章,主要是根据promise/A+里面的规范写的,
class DesignPromise {
constructor(handleFunc) {
this.state = 'pending'
this.value = undefined
this.fulfilledList = []
handleFunc(this.triggerResolve.bind(this))
}
triggerResolve(val) {
setTimeout(() => {
if (this.state !== 'pending') return;//不是等待态(Pending)就是已完成(Fulfilled)和已(Rejected),状态改变后,不能变为其他值,直接return
this.state = val
this.state = 'fulfilled'
this.fulfilledList.forEach(item => { item(val) })
this.fulfilledList = []
}, 0)
}
then(onFulfilled, onRejected) {
const { value, state } = this
return new DesignPromise((onNextFulfilled, onNextReject) => {
function onFinalFulfilled(val) {
const res = onFulfilled(val)
//这里参考的是规范里的2.2.7
/*If either onFulfilled or onRejected returns a value x, run the Promise Resolution Procedure [[Resolve]](promise2, x).
If either onFulfilled or onRejected throws an exception e, promise2 must be rejected with e as the reason.
If onFulfilled is not a function and promise1 is fulfilled, promise2 must be fulfilled with the same value as promise1.
If onRejected is not a function and promise1 is rejected, promise2 must be rejected with the same reason as promise1.*/
if (typeof onFulfilled !== 'function') {
//不是函数时
onNextFulfilled(val)
} else {
if (res && typeof res.then == 'function') {
//说明他是一个promise
res.then(onNextFulfilled)
} else {
onNextFulfilled(res)
}
}
}
switch (state) {
case 'pending':
this.fulfilledList.push(onFinalFulfilled)
break;
}
})
}
static all(list) {
return new DesignPromise((resolve, reject) => {
let count = 0;
const values = [];
for (const [i, customPromiseInstance] of list.entries()) {
customPromiseInstance
.then(
res => {
values[i] = res;
count++;
if (count === list.length) resolve(values);
},
err => {
reject(err);
}
)
}
});
}
}
const createPromise = function (time) {
return new DesignPromise(function (resolve, reject) {
setTimeout(function () {
resolve(new Date().getTime())
}, time)
})
}
const promiseInstance = createPromise(1000)
promiseInstance.then(function () {
console.log("promise.then: hello world");
});
Promise.all([createPromise(2000), createPromise(1000)])
.then(res => {
console.log("Promise.all", res);
});