const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
// 手写promise
function myPromise(excutor) {
let self = this
self.value = null
self.error = null
self.onfulfilledCallBack = []
self.onrejectedCallBack = []
self.status = PENDING
const resolve = (value) => {
if (self.status != PENDING) return
setTimeout(() => {
self.status = FULFILLED
self.value = value
self.onfulfilledCallBack.forEach(callback => callback(self.value))
})
}
const reject = (error) => {
if (self.status != PENDING) return
setTimeout(() => {
self.status = REJECTED
self.error = error
self.onrejectedCallBack.forEach(callback => callback(self.error))
})
}
excutor(resolve, reject)
}
// then
myPromise.prototype.then = function (onfulfilled, onrejected) {
// 校验参数
onfulfilled = typeof onfulfilled == 'function' ? onfulfilled : value => value
onrejected = typeof onrejected == 'function' ? onrejected : error => {
throw error
}
let bridgePromise
let self = this
if (self.status == PENDING) {
return bridgePromise = new myPromise((resolve, reject) => {
self.onfulfilledCallBack.push((value) => {
try {
let x = onfulfilled(value)
// resolvePromise
resolvePromise(bridgePromise, x, resolve, reject)
resolve(x)
} catch (e) {
reject(e)
}
})
// 同理
self.onrejectedCallBack.push((error) => {
try {
let x = onrejected(error)
// resolvePromise
resolvePromise(bridgePromise, x, resolve, reject)
} catch (e) {
reject(e)
}
})
})
} else if (self.status == FULFILLED) {
return bridgePromise = new myPromise((resolve, reject) => {
setTimeout(() => {
try {
let x = onfulfilled(self.value)
resolvePromise(bridgePromise, x, resolve, reject)
} catch (e) {
reject(e)
}
})
})
} else {
setTimeout(() => {
try {
let x = onrejected(self.error)
resolvePromise(bridgePromise, x, resolve, reject)
} catch (e) {
reject(e)
}
})
}
return this
}
// catch
myPromise.prototype.catch = function (onrejected) {
return this.then(null, onrejected)
}
function resolvePromise(bridgePromise, x, resolve, reject) {
// 判断是否promise
if (x instanceof myPromise) {
// 是 则继续resolve
if (x.status == PENDING) {
x.then(y => {
resolvePromise(bridgePromise, y, resolve, reject)
}, error => {
reject(error)
})
} else {
x.then(resolve, reject)
}
} else {
// 非promise 直接返回
resolve(x)
}
}
// promise 的resolve方法
Promise.resolve = function (params) {
// 判断是否promise
if (params instanceof Promise) {
return params
}
return new Promise((resolve, reject) => {
if (params && params.then && typeof params.then == 'function') {
params.then(resolve, reject)
} else {
resolve(params)
}
})
}
// promise reject
Promise.reject = function (reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
// promise finally
Promise.prototype.finally = function (callback) {
this.then(value => {
return Promise.resolve((callback()).then(() => {
return value
}, error => {
return new Promise.resolve((callback()).then(() => {
throw error
}))
}))
})
}
// promise all
Promise.all = function (promises) {
return new Promise((resolve, reject) => {
let result = []
let index = 0
let len = promises.length
if (len === 0) {
resolve(result)
return
}
for (let i = 0
// 为什么不直接 promise[i].then, 因为promise[i]可能不是一个promise
Promise.resolve(promise[i]).then(data => {
result[i] = data
index++
if (index === len) resolve(result)
}).catch(err => {
reject(err)
})
}
})
}
// promise race
Promise.race = function (promises) {
return new Promise((resolve, reject) => {
let len = promises.length
if (len === 0) return
for (let i = 0
Promise.resolve(promise[i]).then(data => {
resolve(data)
return
}).catch(err => {
reject(err)
return
})
}
})
}