// 手写一个promise
// 思路
// 1、 他是一个类, 传递一个执行器进去, 这个执行器会立即执行
// 2、 有3种状态 成功fulfilled 失败rejected 等待pending
// 3、 resolve reject是用来改变状态的,可以通过调用来更改状态,可接受参数作为执行的结果
// 4、处理异步操作
// 5、处理多次then的调用
// 6、实现链式调用 2个点,then返回promise对象 value是上一次返回的值
// 7、捕获构造器函数错误和成功失败函数的错误
// 8、then允许不传递参数
// 9、promise不允许返回实例本身
// 10、静态方法all方法的实现
// 11、静态方法resolve方法的实现
// 12、finally方法的实现
// 13、catch方法的实现
// const p = new Promies((resovle, rejuect) => {
// })
// p.then((value)=>{},(error)=>{}) then可以多次调用
// .then((value)=>{},(error)=>{})
// .then((value)=>{},(error)=>{})
const PENGDING = 'pengding'
const REJECTED = 'rejected'
const FULFILLED = 'fulfilled'
const resolvePromise = (promise2, returnValue, resolve, reject) => {
if (promise2 === returnValue) {
return reject(new Error('不能返回当前promise实例'))
}
if (returnValue instanceof MyPromise) {
// 返回promise
returnValue.then(resolve, reject)
} else {
// 返回常量
resolve(returnValue)
}
}
class MyPromise {
constructor(executor) {
try {
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e)
}
}
status = PENGDING
// 成功之后的值
value = undefined
// 失败之后的原因
resion = undefined
// 定义成功回调
successCallback = []
// 定义失败回调
errorCallback = []
// finally方法
finally = (callback) => {
return this.then(value => {
return MyPromise.resolve(callback()).then(() => value)
}, error => {
return MyPromise.resolve(callback()).then(() => {
throw error
})
})
}
// catch方法
catch = (failCallback) => {
return this.then(undefined, failCallback)
}
resolve = value => {
if (this.status !== PENGDING) {
return
}
this.status = FULFILLED
this.value = value
// 异步的情况
// this.successCallback && this.successCallback(this.value)
// 上面代码优化成多次调用then方法
while (this.successCallback.length) this.successCallback.shift()()
}
reject = resion => {
if (this.status !== PENGDING) {
return
}
this.status = REJECTED
this.resion = resion
// 异步的情况
// this.errorCallback && this.errorCallback(this.resion)
// 上面代码优化成多次调用then方法
while (this.errorCallback.length) this.errorCallback.shift()()
}
then(successCallback = v => v, errorCallback = e => {
throw e
}) {
const promise2 = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED) {
setTimeout(() => {
try {
const returnValue = successCallback(this.value)
resolvePromise(promise2, returnValue, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
}
if (this.status === REJECTED) {
setTimeout(() => {
try {
const returnValue = errorCallback(this.resion)
resolvePromise(promise2, returnValue, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
}
if (this.status = PENGDING) {
this.successCallback.push(() => {
setTimeout(() => {
try {
const returnValue = successCallback(this.value)
resolvePromise(promise2, returnValue, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
this.errorCallback.push(() => {
setTimeout(() => {
try {
const returnValue = errorCallback(this.resion)
resolvePromise(promise2, returnValue, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
}
})
return promise2
}
static all(arr) {
const result = []
let index = 0
return new MyPromise((resolve, reject) => {
const add = (key, value) => {
result[key] = value
index++
if (index === arr.length) {
resolve(result)
}
}
arr.forEach((item, index) => {
if (item instanceof MyPromise) {
item.then(value => add(index, value), error => reject(error))
} else {
add(index, item)
}
})
})
}
static resolve(value) {
if (value instanceof MyPromise) return value
return new MyPromise((resolve) => {
resolve(value)
})
}
}
// const myPromise = new MyPromise((resolve, reject) => {
// setTimeout(() => {
// // reject('失败')
// resolve('成功')
// }, 2000)
// // resolve('成功')
// })
// 多次调用then
// myPromise.then(v => {
// console.log(v, 777)
// }, e => {
// console.log(e, 888)
// })
// myPromise.then(v => {
// console.log(v, 11)
// }, e => {
// console.log(e, 22)
// })
// myPromise.then(v => {
// console.log(v, 33)
// }, e => {
// console.log(e, 44)
// })
// 链式调用then方法
// myPromise.then((v) => {
// console.log(v, 'v1')
// return 2000
// }, (e) => {
// return 3000
// })
// .then((v) => {
// console.log(v, 'v2')
// }, e => console.log(e.message, 6666))
// then不传递参数
// myPromise.then()
// .then()
// .then(v => console.log(v, 6666), e => console.log(e, 777))
// all方法测试
// const p1 = () => new MyPromise((resolve, reject) => {
// setTimeout(() => {
// reject('失败')
// // resolve('p1')
// }, 2000)
// // resolve('成功')
// })
// const p2 = () => new MyPromise((resolve, reject) => {
// resolve('p2')
// })
// MyPromise.all([2, 4, p1(), p2(), 789]).then(v=>console.log(v,7777),e=>console.log(e,88))
// 测试resolve方法
// MyPromise.resolve(myPromise).then(v=>console.log(v,88))
// 测试finally方法
// const myPromise = new MyPromise((resolve, reject) => {
// setTimeout(() => {
// // reject('失败')
// resolve('成功11')
// }, 2000)
// // resolve('成功')
// })
// const p1 = () => new MyPromise((resolve, reject) => {
// resolve('成功222')
// })
// myPromise.finally(() => {
// console.log('finally')
// return p1()
// }).then(v => console.log(v, 777))
// 测试catch方法
const myPromise = new MyPromise((resolve, reject) => {
// setTimeout(() => {
// reject('失败')
// // resolve('成功11')
// }, 2000)
// resolve('成功')
reject('失败')
})
myPromise.then(v => console.log(v, 777)).catch(e=>console.log(e,65))