代码语言:javascript复制
/**
* class MyPromise
* for learn promise
*/
class MyPromise {
state = 'pending' // 三种状态 不可逆改变 pending未完成 reject错误 fulfilled完成
value = undefined // fulfilled 状态 返回结果
reason = undefined // reject 状态 返回原因
resolveCallBacks = [] // resolve事件回调数组
rejectCallBacks = [] // reject事件回调数组
constructor(fn) {
// resolve 修改状态和结果
const resolveHandler = (value) => {
if (this.state === 'pending') {
this.state = 'fulfilled'
this.value = value
this.resolveCallBacks.forEach(fn => {
fn(value)
})
}
}
// reject 修改状态和原因
const rejectHandler = (reason) => {
if (this.state === 'pending') {
this.state = 'rejected'
this.reason = reason
this.rejectCallBacks.forEach(fn => {
fn(reason)
})
}
}
// 监听错误
try {
fn(resolveHandler, rejectHandler)
} catch (err) {
rejectHandler(err)
}
}
// 链式调用 返回一个新的 MyPromise 对象
then(fn1, fn2) {
// 此处处理防止后续操作 常量被当作函数从而引发的错误
fn1 = typeof fn1 === 'function' ? fn1 : (v) => {
v
}
fn2 = typeof fn2 === 'function' ? fn2 : (e) => {
e
}
// pending状态时候 将回调函数纳入各状态的回调数组 等待处理
if (this.state === 'pending') {
return new MyPromise((resolve,reject)=>{
try {
this.resolveCallBacks.push(()=>{
fn1(this.value)
})
this.rejectCallBacks.push(()=>{
fn2(this.reason)
})
}catch (e) {
reject(e)
}
})
}
// fulfilled 回调触发 返回新的 fulfilled(resolve) 状态的 MyPromise 对象
if (this.state === 'fulfilled') {
return new MyPromise((resolve, reject) => {
try {
const newValue = fn1(this.value)
resolve(newValue)
} catch (e) {
reject(e)
}
})
}
// rejected 回调触发 返回新的 rejected(reject) 状态的 MyPromise 对象
if (this.state === 'rejected') {
return new MyPromise((resolve, reject) => {
try {
const newReason = fn2(this.reason)
reject(newReason)
} catch (e) {
reject(e)
}
})
}
}
// 语法糖 只接收 rejected回调事件
catch(fn) {
return this.then(null, fn)
}
}
// 实际返回一个新的 MyPromise 对象 但只做 resolve处理
MyPromise.resolve = function (value) {
return new MyPromise((resolve,reject)=>{
resolve(value)
})
}
// 实际返回一个新的 MyPromise 对象 但只做 rejected处理
MyPromise.reject = function (reason) {
return new MyPromise((resolve,reject)=>{
reject(reason)
})
}
// 执行多个MyPromise 完成后统一返回
MyPromise.all = function (promiseList = []) {
return new MyPromise((resolve,reject)=>{
const result = [];
const length = promiseList.length;
let resolveCount = 0;
promiseList.forEach(p=>{
p.then(v=>{
result.push(v)
resolveCount
if(resolveCount===length){
resolve(result)
}
}).catch(e=>reject(e));
})
})
}
// 执行多个MyPromise 有一个完成就返回
MyPromise.race = function (promiseList = []) {
return new MyPromise((resolve,reject)=>{
let isResolved = false
promiseList.forEach(p=>{
p.then(v=>{
if(!isResolved){
resolve(v)
isResolved = true
}
}).catch(e=>reject(e));
})
})
}