$ 正常的promise用法
let p1 = new Promise((resolve, reject) => {
let async_request = true
if (async_request) {
resolve({ data: 'p1 resolved' })
} else {
reject({msg: 'p1 rejected'})
}
})
p1.then(res => {
console.log(res.data)
})
$ 手写的Promise
// promise是个构造函数
function myPromise(excutor) {
let self = this
self.status = 'pending'
self.value = null
self.reason = null
// 解决异步问题,发布订阅模式。暂存.then的回调函数
self.onFulfilledCallbacks = []
self.onRejectedCallbacks = []
function resolve(value) {
if (self.status === 'pending') {
self.value = value
self.status = 'fulfilled'
// 执行.then里暂存的回调函数
self.onFulfilledCallbacks.forEach(fn => fn(value))
}
}
function reject(reason) {
if (self.status === 'pending') {
self.reason = reason
self.status = 'rejected'
self.onRejectedCallbacks.forEach(fn => fn(reason))
}
}
// 立即执行
excutor && excutor(resolve, reject)
}
myPromise.prototype.then = function(onFulfilled, onRejected) {
let _this = this
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (data) => { resolve(data) }
onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err }
// 如果是链式调用,判断传入的参数是否是promise,如果是,继续执行.then,如果不是,返回结果
if (self.status === 'fulfilled') {
return new myPromise((resolve, reject) => {
try {
let x = onFulfilled(self.value) // 将上一个promise结果当作番薯传给传入的promise
x instanceof myPromise ? x.then(resolve, reject) : resolve(x)
} catch (error) {
reject(error)
}
})
}
if (self.status === 'rejected') {
return new myPromise((resolve, reject) => {
try {
let x = onRejected(self.reason)
x instanceof myPromise ? x.then(resolve, reject) : reason
} catch (error) {
reject(error)
}
})
}
// 解决异步任务回调执行问题,添加订阅模式
if (self.status === 'pending') {
return new myPromise((resolve, reject) => {
self.onFulfilledCallbacks.push(() => {
let x = onFulfilled(self.value)
x instanceof myPromise ? x.then(resolve, reject) : resolve(x)
})
self.onRejectedCallbacks.push(() => {
let x = onRejected(self.reason)
x instanceof myPromise ? x.then(resolve, reject) : resolve(x)
})
})
}
}
# 测试可行性
let mp1 = new myPromise((resolve, reject) => {
let ok = true
if (ok) {
setTimeout(() => {
console.log('进入setTimeout')
resolve({data: 'resolve data_setTimeout'})
}, 1000)
} else {
reject({ message: 'myPromise error' })
}
})
mp1.then(res => {
console.log(res.data)
}, err => {
console.log(err.message)
})