写在前面
如果本文对您有所帮助,就请点个关注吧!
手写一个Promise
源代码
const reslovePromise = (promise2, x, reslove, reject) => {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof iPromise) {
x.then.call(x, res => {
reslovePromise(promise2, res, reslove, reject)
}, err => {
reject(err)
})
} else {
reslove(x)
}
}
class iPromise {
constructor(executor) {
this.state = 'pending'
this.value = undefined
this.reason = undefined
this.onResolvedCallbacks = []
this.onRejectedCallbacks = []
const reslove = value => {
if (value instanceof iPromise) {
return value.then(reslove, reject)
}
setTimeout(() => {
if (this.state === 'pending') {
this.state = 'fulfilled'
this.value = value
this.onResolvedCallbacks.forEach(fn => fn())
}
}, 0)
}
const reject = reason => {
setTimeout(() => {
if (this.state === 'pending') {
this.state = 'rejected'
this.reason = reason
this.onRejectedCallbacks.forEach(fn => fn())
}
}, 0)
}
executor(reslove, reject)
}
then(onFulfilled, onRejected) {
const promise2 = new iPromise((reslove, reject) => {
if (this.state === 'pending') {
this.onResolvedCallbacks.push(() => {
setTimeout(() => {
const x = onFulfilled(this.value)
reslovePromise(promise2, x, reslove, reject)
}, 0)
})
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
const x = onRejected(this.reason)
reslovePromise(promise2, x, reslove, reject)
}, 0)
})
}
if (this.state === 'fulfilled') {
setTimeout(() => {
const x = onFulfilled(this.value)
reslovePromise(promise2, x, reslove, reject)
}, 0)
}
if (this.state === 'rejected') {
setTimeout(() => {
const x = onRejected(this.reason)
reslovePromise(promise2, x, reslove, reject)
}, 0)
}
})
return promise2
}
static reslove(value) {
return new iPromise((reslove, reject) => {
reslove(value)
})
}
static reject(reason) {
return new iPromise((reslove, reject) => {
reject(reason)
})
}
static race(promises) {
return new iPromise((resolve, reject) => {
promises.forEach(promise => {
promise.then(resolve, reject)
})
})
}
static all(promises) {
return new Promise((res, rej) => {
var arr = []
var times = 0;
function processResult(index, result) {
arr[index] = result
times++;
if (times == promiseArr.length) {
res(arr)
}
}
for (let i = 0; i < promises.length; i++) {
var oPromise = promises[i];
if (typeof oPromise.then == 'function') {
oPromise.then(function (val) {
processResult(i, val)
}, function (reason) {
rej(reason)
})
} else {
processResult(i, oPromise)
}
}
})
}
}
网友评论