在不了解 Promise 的情况下,建议先阅读 Promise 的使用篇
注意点:
- executor 函数立即执行
- 状态不可逆 (pending -> fulfilled 或者 pending -> rejected)
- resolve/reject 执行之后立即改变状态
- .then 里面的内容异步执行并且返回一个新的 Promise
- 在不出现错误的情况下 onFulfilled/onRejected 的返回值作为下一个 Promise 的成功回调的参数
// 状态常量
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
// Promise 类
function LPromise(executor) {
this.status = PENDING // 当前状态
this.value = undefined // 当前值
this.onFulfilled = [] // 缓存成功回调
this.onRejected = [] // 缓存失败回调
this.resolveFn = body => { // resolve 函数
// 只有当当前状态为 pedding 才触发
if (this.status !== PENDING) return
this.status = FULFILLED
this.value = body
// 触发成功的回调
// 主要用于 executor 里面含有异步逻辑的处理
// 当 excutor 函数里面是同步逻辑的时候 this.onFulfilled 是一个空的数组
this.onFulfilled.forEach(cb => cb())
}
this.rejectFn = error => { // reject 函数
if (this.status !== PENDING) return
this.status = REJECTED
this.value = error
this.onRejected.forEach(cb => cb())
}
// 立即执行 executor 函数
// try catch 是为了防止 executor 里面内容发生异常
try {
executor(this.resolveFn, this.rejectFn)
} catch (e) {
this.rejectFn(e)
}
}
// then 方法
// 接收一个成功回调(onFulfilled) 一个失败回调(onRejected)
LPromise.prototype.then = function (onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : () => { }
onRejected = typeof onRejected === 'function' ? onRejected : () => { }
// 链式调用
const _promise = new LPromise((resolve, reject) => {
// 异步执行 then 函数里面的内容
setTimeout(() => {
// 当 excutor 函数里面是同步逻辑或者是执行在这之前的异步函数的时候 才会走到这里
if (this.status === FULFILLED) {
const result = onFulfilled(this.value)
resolve(result)
}
// 当 excutor 函数里面是同步逻辑或者是执行在这之前的异步函数时候 才会走到这里
if (this.status === REJECTED) {
const result = onRejected(this.value)
reject(result)
}
// 当 excutor 函数里面是异步逻辑并异步在这之后执行的时候 才会走到这里
if (this.status === PENDING) {
// 缓存用户传进来的 onFulfilled、onRejected 回调函数
// 当用户主动触发 resolve/reject 的时候再调用
this.onFulfilled.push(() => {
// 将当前回调返回的结果
// 返回到下一个 Promise 的成功回调中
try {
const result = onFulfilled(this.value)
resolve(result)
} catch (e) {
reject(e)
}
})
this.onRejected.push(() => {
// 将当前回调返回的结果
// 返回到下一个 Promise 的成功回调中
try {
const result = onRejected(this.value)
resolve(this.value)
} catch (e) {
reject(e)
}
})
}
}, 0)
})
return _promise
}
// 捕获错误
// 接收一个失败回调(onRejected)
LPromise.prototype.catch = function (onRejected) {
this.then(null, onRejected)
}
LPromise.resolve = function (value) {
return new LPromise((resolve, reject) => {
resolve(value)
})
}
LPromise.reject = function (value) {
return new LPromise((resolve, reject) => {
reject(value)
})
}
测试
console.log('script start')
const lp1 = new LPromise((resolve, reject) => {
a
})
lp1.then(body => { }, error => {
console.log(error)
})
const lp2 = new LPromise((resolve, reject) => {
setTimeout(() => {
resolve('sleep 1000ms')
}, 1000)
})
lp2.then(body => {
console.log(body)
return 1
}, null)
const lp3 = new LPromise((resolve, reject) => {
setTimeout(() => {
reject('失败了')
}, 1000)
})
lp3.then()
lp3.catch(fail => console.log(fail))
const lp4 = new LPromise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 1)
})
lp4
.then(body => {
console.log(body)
return '嘻哈'
}, null)
.then(body => {
console.log(body)
return 1
}, null)
const lp5 = new LPromise((resolve, reject) => {
setTimeout(() => {
resolve('测试 then 里面抛出异常')
}, 10)
})
lp5
.then(body => {
console.log(body)
console.log(b)
return '嘻哈'
}, null)
.then(null, error => {
console.log('上一个 then 里面抛出了异常,被我接收到了哦!!')
console.log(error)
})
LPromise.resolve(setTimeout(() => console.log('setTimeout'), 1000))
.then(body => console.log(body, 'Promise.resolve'))
LPromise.reject(setTimeout(() => console.log('setTimeout'), 1000))
.then(null, body => console.log(body, 'Promise.reject'))
console.log('script end')
以上输出结果:
> script start
> script end
> ReferenceError: a is not defined
> 1
> 嘻哈
> 13, Promise.resolve
> 15, Promise.reject
> 测试 then 里面抛出异常
> 上一个 then 里面抛出了异常,被我接收到了哦!!
> ReferenceError: b is not defined
> sleep 1000ms
> 失败了
> setTimeout
> setTimeout
【笔记不易,如对您有帮助,请点赞,谢谢】