class mypromise {
constructor(executor) {
// 存状态
this.state = 'pending'
// 存成功的值
this.value = undefined
// 存失败的值
this.reason = undefined
// 成功和失败的事件队列
this.onFulfilledCallback = []
this.onRejectedCallback = []
// resolve逻辑
const resolve = (value) => {
if (this.state === 'pending') {
this.state = 'fulfilled'
this.value = value
// 等真正异步结束调resolve的时候,在依次执行成功回调队列
this.onFulfilledCallback.forEach(fn => fn())
}
}
// reject逻辑
const reject = (reason) => {
if (this.state === 'pending') {
this.state = 'rejected'
this.reason = reason
// 等真正异步结束调resolve的时候,在依次执行失败回调队列
this.onRejectedCallback.forEach(fn => fn())
}
}
// 立即执行传入promise的函数:因此promise参数函数的函数体内语句是同步的
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
then (onFulfilled, onRejected) {
// 实现链式调用,因此要返回一个promise
let promise2 = new mypromise((resolve, reject) => {
if (this.state === 'fulfilled') {
// 异步是因为,如果同步的话,resolvePromise传入的promise2还拿不到
setTimeout(() => {
try {
// 为了下一次的then调用能够拿到上一次then函数里面的返回值
let x = onFulfilled(this.value)
// 为了实现then函数里面返回promise的情况
resolverPomise(x, resolve, reject, promise2)
} catch (error) {
reject(error)
}
}, 0)
}
if (this.state === 'rejected') {
setTimeout(() => {
try {
// 为了下一次的then调用能够拿到上一次then函数里面的返回值
let x = onRejected(this.reason)
// 为了实现then函数里面返回promise的情况
resolverPomise(x, resolve, reject, promise2)
} catch (error) {
reject(error)
}
}, 0)
}
// 处理异步得时候,就把要then里面要执行得函数暂存到队列
// 直到调用了 resolve或者reject再去执行then里面的函数
if (this.state === 'pending') {
this.onFulfilledCallback.push(() => {
setTimeout(() => {
try {
// 为了下一次的then调用能够拿到上一次then函数里面的返回值
let x = onFulfilled(this.value)
// 为了实现then函数里面返回promise的情况
resolverPomise(x, resolve, reject, promise2)
} catch (error) {
reject(error)
}
}, 0)
})
this.onRejectedCallback.push(() => {
setTimeout(() => {
try {
// 为了下一次的then调用能够拿到上一次then函数里面的返回值
let x = onRejected(this.reason)
// 为了实现then函数里面返回promise的情况
resolverPomise(x, resolve, reject, promise2)
} catch (error) {
reject(error)
}
}, 0)
})
}
})
return promise2
}
}
function resolverPomise (x, resolve, reject, promise2) {
// 为了捕获return自己的错误情况
if (x === promise2) {
console.error('循环引用')
}
if (x instanceof mypromise) {
x.then((value) => {
resolve(value)
}, err => {
reject(err)
})
} else {
resolve(x)
}
}
// 四个API
mypromise.resolve = function (val) {
return new mypromise((resolve, reject) => {
resolve(val)
})
}
mypromise.reject = function (reason) {
return new mypromise((resolve, reject) => {
reject(reason)
})
}
mypromise.race = function (promises) {
return new mypromise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(resolve, reject)
}
})
}
mypromise.all = function (promises) {
let arr = []
let count = 0
function processData (index, data, resolve) {
arr[index] = data
count++
if (count === promises.length) {
resolve(arr)
}
}
return new mypromise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(res => {
processData(i, res, resolve)
}, reject)
}
})
}
// 测试代码
let p1 = new mypromise((resolve, reject) => {
setTimeout(() => {
resolve(100)
}, 1000)
})
let p2 = new mypromise((resolve, reject) => {
setTimeout(() => {
resolve(200)
}, 2000)
})
let p3 = new mypromise((resolve, reject) => {
setTimeout(() => {
resolve(300)
}, 3000)
})
mypromise.all([p1, p2, p3]).then((res) => {
console.log(res)
})
实现一个基础的promise
最新推荐文章于 2024-09-02 17:34:07 发布