作者:奥兰度
// 异步 Promise + 错误处理 + 链式
// new Promise(() => {}).then(() => { return 0}).then((val) => { /* 0 */ })
class MyPromise {
constructor (executor) {
this.status = 'pending'
this.value = undefined // resolve value
this.reason = undefined // reject error
// 存放 then 成功和失败的回调,延后运行
this.onResolveCallbacks = [] // then(() => {}, () => {})
this.onRejectedCallbacks = [] // catch((err) => {})
let resolve = (value) => {
if (this.status === 'pending') {
this.status = 'resolved'
if (value instanceof MyPromise) {
setTimeout(()=> {
const then = value.then
if (typeof then === 'function') {
then.call(value, val => {
this.value = val
}, err => {
if (called) return
called = true
this.reason = err
})
}
})
} else {
this.value = value
}
// 收集的回调运行一下
this.onResolveCallbacks.forEach(fn => fn())
}
}
let reject = (reason) => {
if (this.status === 'pending') {
this.status = 'rejected'
this.reason = reason
// 收集的回调运行一下
this.onRejectedCallbacks.forEach(fn => fn())
}
}
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
then(onFullFilled, onRejected) {
onFullFilled = typeof onFullFilled === 'function' ? onFullFilled : value => value
onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err }
let transPromise
transPromise = new MyPromise((resolve, reject) => {
if (this.status === 'resolved') {
try {
setTimeout(() => {
// resolve 后的 then 中 onFullFilled 返回的值是下一个 then 的 onFullFilled 接收的值
if (this.value instanceof MyPromise) {
this.value = this.value.value
}
const value = onFullFilled(this.value)
resolvePromise(transPromise, value, resolve, reject)
})
} catch (e) {
reject(e)
}
}
if (this.status === 'rejected') {
setTimeout(() => {
try {
const value = onRejected(this.reason)
resolvePromise(value)
} catch(e) {
reject(e)
}
})
}
// 收集回调,因为使用了 this 传递,所以值一直存在的
if (this.status === 'pending') {
this.onResolveCallbacks.push(() => {
setTimeout(() => {
try {
if (this.value instanceof MyPromise) {
this.value = this.value.value
}
const value = onFullFilled(this.value)
resolvePromise(transPromise, value, resolve, reject)
} catch (e) {
reject(e)
}
})
})
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const value = onRejected(this.reason)
resolvePromise(value)
} catch (e) {
reject(e)
}
})
})
}
})
function resolvePromise (transPromise, value, resolve, reject) {
if (transPromise === value) {
return reject(new TypeError('循环引用'))
}
let called // 是否调用成功或失败
// 看 value 是否是个 Promise
if (value !== null && (typeof value === 'object' || typeof value === 'function')) { // value instanceof MyPromise
try {
const then = value.then
if (typeof then === 'function') {
then.call(value, val => {
if (called) return
called = true
resolvePromise(transPromise, val, resolve, reject)
}, err => {
if (called) return
called = true
reject(err)
})
}
} catch (e) {
if (called) return
called = true
reject(e)
}
} else {
resolve(value)
}
}
return transPromise
}
defer () {
let dfd = {}
dfd.promise = new Promise((resolve, reject) => {
dfd.resolve = resolve
dfd.reject = reject
})
return dfd
}
deferred () {
this.defer()
}
}
const myPromiseT = new MyPromise((resolve, reject) => {
// setTimeout(() => {
resolve('foo');
// }, 300);
});
let promiseA = myPromiseT.then(res => {
console.log(res); return res
})
let promiseB = promiseA.then(res => {
console.log(res); return res
})
let promiseC = promiseB.then(res => {
console.log(res); return res
})
console.log('bar')
作者:
作者:
作者: