手撕 Promise
前言
不论是前端日常开发,还是前端面试题,总是会遇到 Promise 相关的问题。因此今天就来一探究竟,揭开 Promise 的神秘面纱。
基本结构
- 构造函数里传入一个函数,它有两个形参
resolve
、reject
resolve
函数成功时执行reject
函数失败时执行
class Promise {
constructor(executor) {
// resolve 函数
const resolve = (data) => {}
// reject 函数
const reject = (data) => {}
// 同步调用「执行器函数」
executor(resolve, reject)
}
}
const p = new Promise((resolve, reject) => {
resolve('ok')
})
console.log(p)
三种状态实现
一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise 对象的状态改变,只有两种可能:从 pending 变为 fulfilled 和从 pending 变为 rejected。
- 进行中
pending
- 已成功
fulfilled
- 已失败
rejected
- 状态只能改变一次
在开始之前,我们先看 Chrome
内置的 Promise
输出结果:
const p = new Promise((resolve, reject) => {
// resolve('ok')
// reject('error')
// throw 'Error'
})
console.log(p)
- 首先
Promise
传入的函数不执行任何操作:
resolve('ok')
结果如下:
reject('error')
结果如下:
throw 'Error'
结果如下:
- 状态只能改变一次,运行如下代码查看效果:
const p = new Promise((resolve, reject) => {
resolve('ok')
reject('error')
// throw 'Error'
})
console.log(p)
通过上面打印的结果,PromiseState
指当前状态,PromiseResult
指结果值。现在我们模仿上面的运行结果实现如下:
pending
点击查看代码
class Promise {
// 构造器
constructor(executor) {
this.PromiseState = 'pending' // 进行中
this.PromiseResult = null // 结果值
// resolve 函数
const resolve = (data) => {}
// reject 函数
const reject = (data) => {}
// 同步调用「执行器函数」
executor(resolve, reject)
}
}
const p = new Promise((resolve, reject) => {
// resolve('ok')
// reject('error')
// throw 'Error'
})
console.log(p)
fulfilled
点击查看代码
class Promise {
// 构造器
constructor(executor) {
this.PromiseState = 'pending' // 进行中
this.PromiseResult = null // 结果值
// resolve 函数
const resolve = (data) => {
// 修改对象状态
this.PromiseState = 'fulfilled' // 已成功
// 设置对象结果值
this.PromiseResult = data
}
// reject 函数
const reject = (data) => {}
// 同步调用「执行器函数」
executor(resolve, reject)
}
}
rejected
点击查看代码
class Promise {
// 构造器
constructor(executor) {
this.PromiseState = 'pending' // 进行中
this.PromiseResult = null // 结果值
// resolve 函数
const resolve = (data) => {
// 修改对象状态
this.PromiseState = 'fulfilled' // 已成功
// 设置对象结果值
this.PromiseResult = data
}
// reject 函数
const reject = (data) => {
// 修改对象状态
this.PromiseState = 'rejected' // 已失败
// 设置对象结果值
this.PromiseResult = data
}
// 捕获 throw
try {
// 同步调用「执行器函数」
executor(resolve, reject)
} catch (error) {
// 修改 promise 对象状态为失败
reject(error)
}
}
}
状态只能改变一次
目前我们的 Promise 运行如下代码:
const p = new Promise((resolve, reject) => {
resolve('ok')
reject('error')
// throw 'Error'
})
console.log(p)
打印结果如下:
输出的结果明显有问题,正确的状态应是 fulfilled
,因为状态只能是 pending
变成 fulfilled
,或者 pending
变成 rejected
,所以通过判断状态是否为 pending
即可修复该问题。
优化代码如下:
点击查看代码
class Promise {
// 构造器
constructor(executor) {
this.PromiseState = 'pending' // 进行中
this.PromiseResult = null // 结果值
// resolve 函数
const resolve = (data) => {
// 判断状态是否为 pending
if (this.PromiseState !== 'pending') return
// 修改对象状态
this.PromiseState = 'fulfilled' // 已成功
// 设置对象结果值
this.PromiseResult = data
}
// reject 函数
const reject = (data) => {
// 判断状态是否为 pending
if (this.PromiseState !== 'pending') return
// 修改对象状态
this.PromiseState = 'rejected' // 已失败
// 设置对象结果值
this.PromiseResult = data
}
// 捕获 throw
try {
// 同步调用「执行器函数」
executor(resolve, reject)
} catch (error) {
// 修改 promise 对象状态为失败
reject(error)
}
}
}
Promise.prototype.then()
它的作用是为 Promise 实例添加状态改变时的回调函数。then 方法的第一个参数是 resolved 状态的回调函数,第二个参数是 rejected 状态的回调函数,它们都是可选的。
在开始之前,我们先看 Chrome
内置的 Promise
输出结果:
const p = new Promise((resolve, reject) => {
resolve('ok')
// reject('error')
// throw 'Error'
})
p.then((value) => {
console.log(value) // 输出:ok
}, (error) => {
console.warn(error)
})
通过上面运行效果,需要在 Promise
类添加 then
方法:
点击查看代码
class Promise {
// 构造器
constructor(executor) {
this.PromiseState = 'pending' // 进行中
this.PromiseResult = null // 结果值
// resolve 函数
const resolve = (data) => {
// 判断状态是否为 pending
if (this.PromiseState !== 'pending') return
// 修改对象状态
this.PromiseState = 'fulfilled' // 已成功
// 设置对象结果值
this.PromiseResult = data
}
// reject 函数
const reject = (data) => {
// 判断状态是否为 pending
if (this.PromiseState !== 'pending') return
// 修改对象状态
this.PromiseState = 'rejected' // 已失败
// 设置对象结果值
this.PromiseResult = data
}
// 捕获 throw
try {
// 同步调用「执行器函数」
executor(resolve, reject)
} catch (error) {
// 修改 promise 对象状态为失败
reject(error)
}
}
// 添加 then 方法
then(handleResolve, handleReject) {
// 根据 PromiseState 调用对应回调函数
if (this.PromiseState === 'fulfilled') {
// PromiseResult 传递给回调函数的结果值
handleResolve(this.PromiseResult)
}
if (this.PromiseState === 'rejected') {
// PromiseResult 传递给回调函数的结果值
handleReject(this.PromiseResult)
}
}
}
异步实现
按照惯例,先看 Chrome
内置 Promise
的表现:
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('ok')
}, 1000)
// reject('error')
// throw 'Error'
})
p.then((value) => {
console.log(value) // => 1s 后输出 ok
}, (error) => {
console.warn(error)
})
因为 resolve
或 reject
在 setTimeout
内执行时,then
方法的 PromiseState
还是 pending
状态,所以我们就需要在 then
方法里把成功或失败的回调函数存到公用对象,当 resolve
或 reject
执行改变状态时,就调用它们。
优化代码如下:
点击查看代码
class Promise {
// 构造器
constructor(executor) {
this.PromiseState = 'pending' // 进行中
this.PromiseResult = null // 结果值
this.callbacks = {}
// resolve 函数
const resolve = (data) => {
// 判断状态是否为 pending
if (this.PromiseState !== 'pending') return
// 修改对象状态
this.PromiseState = 'fulfilled' // 已成功
// 设置对象结果值
this.PromiseResult = data
// 状态成功时执行回调函数
if (this.callbacks.handleResolve) {
this.callbacks.handleResolve(data)
}
}
// reject 函数
const reject = (data) => {
// 判断状态是否为 pending
if (this.PromiseState !== 'pending') return
// 修改对象状态
this.PromiseState = 'rejected' // 已失败
// 设置对象结果值
this.PromiseResult = data
// 状态失败时执行回调函数
if (this.callbacks.handleReject) {
this.callbacks.handleReject(data)
}
}
// 捕获 throw
try {
// 同步调用「执行器函数」
executor(resolve, reject)
} catch (error) {
// 修改 promise 对象状态为失败
reject(error)
}
}
// 添加 then 方法
then(handleResolve, handleReject) {
// 根据 PromiseState 调用对应回调函数
if (this.PromiseState === 'fulfilled') {
// PromiseResult 传递给回调函数的结果值
handleResolve(this.PromiseResult)
}
if (this.PromiseState === 'rejected') {
// PromiseResult 传递给回调函数的结果值
handleReject(this.PromiseResult)
}
// 等待状态时保存 handleResolve 和 handleReject 函数,后面改变状态时调用
if (this.PromiseState === 'pending') {
this.callbacks = {
handleResolve,
handleReject,
}
}
}
}
再看 Chrome
内置 Promise
执行多个回调的表现:
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('ok')
// reject('error')
}, 1000)
// reject('error')
// throw 'Error'
})
p.then((value) => {
console.log(value) // 1s 后输出 ok
}, (error) => {
console.warn(error)
})
p.then((value) => {
alert(value) // 1s 后弹出 ok
}, (error) => {
alert(error)
})
我们需要借助 callbacks
数组保存回调函数,因此改造代码如下:
点击查看代码
class Promise {
// 构造器
constructor(executor) {
this.PromiseState = 'pending' // 进行中
this.PromiseResult = null // 结果值
this.callbacks = []
// resolve 函数
const resolve = (data) => {
// 判断状态是否为 pending
if (this.PromiseState !== 'pending') return
// 修改对象状态
this.PromiseState = 'fulfilled' // 已成功
// 设置对象结果值
this.PromiseResult = data
// 状态成功时执行回调函数
this.callbacks.forEach((item) => {
item.handleResolve(data)
})
}
// reject 函数
const reject = (data) => {
// 判断状态是否为 pending
if (this.PromiseState !== 'pending') return
// 修改对象状态
this.PromiseState = 'rejected' // 已失败
// 设置对象结果值
this.PromiseResult = data
// 状态失败时执行回调函数
this.callbacks.forEach((item) => {
item.handleReject(data)
})
}
// 捕获 throw
try {
// 同步调用「执行器函数」
executor(resolve, reject)
} catch (error) {
// 修改 promise 对象状态为失败
reject(error)
}
}
// 添加 then 方法
then(handleResolve, handleReject) {
// 根据 PromiseState 调用对应回调函数
if (this.PromiseState === 'fulfilled') {
// PromiseResult 传递给回调函数的结果值
handleResolve(this.PromiseResult)
}
if (this.PromiseState === 'rejected') {
// PromiseResult 传递给回调函数的结果值
handleReject(this.PromiseResult)
}
// 等待状态时保存 handleResolve 和 handleReject 函数,后面改变状态时调用
if (this.PromiseState === 'pending') {
this.callbacks.push({
handleResolve,
handleReject,
})
}
}
}
then
的返回结果
同步执行 首先看 Chrome
内置 Promise
的运行结果:
const p = new Promise((resolve, reject) => {
resolve('ok')
})
const res = p.then((value) => {
console.log(value)
// 因为这里没有 return 返回值,所以结果是 undefined
}, (error) => {
console.warn(error)
})
console.log(res)
res
的结果如下图:
- 结果是新的
Promise
对象 - 结果值
(PromiseResult)
是then
方法中handleResolve
回调函数的返回值 - 结果状态
(PromiseState)
是fulfilled
实现代码如下:
点击查看代码
class Promise {
// 构造器
constructor(executor) {
this.PromiseState = 'pending' // 进行中
this.PromiseResult = null // 结果值
this.callbacks = []
// resolve 函数
const resolve = (data) => {
// 判断状态是否为 pending
if (this.PromiseState !== 'pending') return
// 修改对象状态
this.PromiseState = 'fulfilled' // 已成功
// 设置对象结果值
this.PromiseResult = data
// 状态成功时执行回调函数
this.callbacks.forEach((item) => {
item.handleResolve(data)
})
}
// reject 函数
const reject = (data) => {
// 判断状态是否为 pending
if (this.PromiseState !== 'pending') return
// 修改对象状态
this.PromiseState = 'rejected' // 已失败
// 设置对象结果值
this.PromiseResult = data
// 状态失败时执行回调函数
this.callbacks.forEach((item) => {
item.handleReject(data)
})
}
// 捕获 throw
try {
// 同步调用「执行器函数」
executor(resolve, reject)
} catch (error) {
// 修改 promise 对象状态为失败
reject(error)
}
}
// 添加 then 方法
then(handleResolve, handleReject) {
// 返回新的 Promise 对象
return new Promise((resolve, reject) => {
// 根据 PromiseState 调用对应回调函数
if (this.PromiseState === 'fulfilled') {
try {
// PromiseResult 传递给回调函数的结果值
const result = handleResolve(this.PromiseResult)
if (result instanceof Promise) {
// 如果是 Promise 类型对象
result.then((v) => {
resolve(v)
}, (e) => {
reject(e)
})
} else {
// 结果状态改为成功
resolve(result)
}
} catch (e) {
reject(e)
}
}
if (this.PromiseState === 'rejected') {
// PromiseResult 传递给回调函数的结果值
handleReject(this.PromiseResult)
}
// 等待状态时保存 handleResolve 和 handleReject 函数,后面改变状态时调用
if (this.PromiseState === 'pending') {
this.callbacks.push({
handleResolve,
handleReject,
})
}
})
}
}
// 示例
const p = new Promise((resolve, reject) => {
resolve('ok')
// reject('error')
})
const res = p.then((value) => {
console.log(value)
// return 'ok'
// return new Promise((resolve, reject) => {
// // resolve('success')
// // reject('error')
// })
throw 'fail'
}, (error) => {
console.warn(error)
})
console.log(res)
then
方法的返回结果
异步状态 首先看 Chrome
内置 Promise
的运行结果:
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('ok')
}, 1000)
})
const res = p.then((value) => {
console.log(value)
// 因为这里没有 return 返回值,所以结果是 undefined
}, (error) => {
console.warn(error)
})
console.log(res)
res
的结果如下图:
对比目前手写 Promise
的 res
输出结果如下图:
观察发现 PromiseState
状态并没有变为 fulfilled
,说明 then
方法中 pending
逻辑需要优化。
改造代码如下:
点击查看代码
class Promise {
// 构造器
constructor(executor) {
this.PromiseState = 'pending' // 进行中
this.PromiseResult = null // 结果值
this.callbacks = []
// resolve 函数
const resolve = (data) => {
// 判断状态是否为 pending
if (this.PromiseState !== 'pending') return
// 修改对象状态
this.PromiseState = 'fulfilled' // 已成功
// 设置对象结果值
this.PromiseResult = data
// 状态成功时执行回调函数
this.callbacks.forEach((item) => {
item.handleResolve(data)
})
}
// reject 函数
const reject = (data) => {
// 判断状态是否为 pending
if (this.PromiseState !== 'pending') return
// 修改对象状态
this.PromiseState = 'rejected' // 已失败
// 设置对象结果值
this.PromiseResult = data
// 状态失败时执行回调函数
this.callbacks.forEach((item) => {
item.handleReject(data)
})
}
// 捕获 throw
try {
// 同步调用「执行器函数」
executor(resolve, reject)
} catch (error) {
// 修改 promise 对象状态为失败
reject(error)
}
}
// 添加 then 方法
then(handleResolve, handleReject) {
// 返回新的 Promise 对象
return new Promise((resolve, reject) => {
// 根据 PromiseState 调用对应回调函数
if (this.PromiseState === 'fulfilled') {
try {
// PromiseResult 传递给回调函数的结果值
const result = handleResolve(this.PromiseResult)
if (result instanceof Promise) {
// 如果是 Promise 类型对象
result.then((v) => {
resolve(v)
}, (e) => {
reject(e)
})
} else {
// 结果状态改为成功
resolve(result)
}
} catch (e) {
reject(e)
}
}
if (this.PromiseState === 'rejected') {
// PromiseResult 传递给回调函数的结果值
handleReject(this.PromiseResult)
}
// 等待状态时保存 handleResolve 和 handleReject 函数,后面改变状态时调用
if (this.PromiseState === 'pending') {
this.callbacks.push({
handleResolve: () => {
try {
const result = handleResolve(this.PromiseResult)
if (result instanceof Promise) {
result.then((v) => {
resolve(v)
}, (e) => {
reject(e)
})
} else {
// 返回结果不是 Promise 对象,状态变为 fulfilled
resolve(result)
}
} catch (e) {
reject(e)
}
},
handleReject: () => {
try {
const result = handleReject(this.PromiseResult)
if (result instanceof Promise) {
result.then((v) => {
resolve(v)
}, (e) => {
reject(e)
})
} else {
// 返回结果不是 Promise 对象,状态变为 fulfilled
resolve(result)
}
} catch (e) {
reject(e)
}
},
})
}
})
}
}
// 示例
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('ok')
// reject('err')
}, 1000)
})
const res = p.then((value) => {
// console.log(value)
return 'success'
// return new Promise((resolve, reject) => {
// resolve('hello promise')
// })
// throw 'fail'
}, (error) => {
console.warn(error) // 返回结果是 undefined
// return 'Err'
// return new Promise((resolve, reject) => {
// reject('hello promise')
// })
// throw 'fail'
})
console.log(res)
then 方法完善
点击查看代码
class Promise {
// 构造器
constructor(executor) {
this.PromiseState = 'pending' // 进行中
this.PromiseResult = null // 结果值
this.callbacks = []
// resolve 函数
const resolve = (data) => {
// 判断状态是否为 pending
if (this.PromiseState !== 'pending') return
// 修改对象状态
this.PromiseState = 'fulfilled' // 已成功
// 设置对象结果值
this.PromiseResult = data
// 状态成功时执行回调函数
this.callbacks.forEach((item) => {
item.handleResolve(data)
})
}
// reject 函数
const reject = (data) => {
// 判断状态是否为 pending
if (this.PromiseState !== 'pending') return
// 修改对象状态
this.PromiseState = 'rejected' // 已失败
// 设置对象结果值
this.PromiseResult = data
// 状态失败时执行回调函数
this.callbacks.forEach((item) => {
item.handleReject(data)
})
}
// 捕获 throw
try {
// 同步调用「执行器函数」
executor(resolve, reject)
} catch (error) {
// 修改 promise 对象状态为失败
reject(error)
}
}
// 添加 then 方法
then(handleResolve, handleReject) {
// 返回新的 Promise 对象
return new Promise((resolve, reject) => {
// 封装处理结果回调函数
const callBackResult = (fn) => {
try {
// PromiseResult 传递给回调函数的结果值
const result = fn(this.PromiseResult)
if (result instanceof Promise) {
// 如果是 Promise 类型对象
result.then((v) => {
resolve(v)
}, (e) => {
reject(e)
})
} else {
// 结果状态改为成功
resolve(result)
}
} catch (e) {
reject(e)
}
}
// 根据 PromiseState 调用对应回调函数
if (this.PromiseState === 'fulfilled') {
callBackResult(handleResolve)
}
if (this.PromiseState === 'rejected') {
callBackResult(handleReject)
}
// 等待状态时保存 handleResolve 和 handleReject 函数,后面改变状态时调用
if (this.PromiseState === 'pending') {
this.callbacks.push({
handleResolve: () => {
callBackResult(handleResolve)
},
handleReject: () => {
callBackResult(handleReject)
},
})
}
})
}
}
catch 方法添加
首先看 Chrome
内置 Promise
的运行结果:
const p = new Promise((resolve, reject) => {
setTimeout(() => {
reject('err')
}, 1000)
})
p.catch((err) => {
console.log(err)
})
输出结果如下图:
对比目前手写 Promise
输出结果如下图:
观察发现,目前手写 Promise
缺少 catch
方法。
改造代码如下:
点击查看代码
class Promise {
// 构造器
constructor(executor) {
this.PromiseState = 'pending' // 进行中
this.PromiseResult = null // 结果值
this.callbacks = []
// resolve 函数
const resolve = (data) => {
// 判断状态是否为 pending
if (this.PromiseState !== 'pending') return
// 修改对象状态
this.PromiseState = 'fulfilled' // 已成功
// 设置对象结果值
this.PromiseResult = data
// 状态成功时执行回调函数
this.callbacks.forEach((item) => {
item.handleResolve(data)
})
}
// reject 函数
const reject = (data) => {
// 判断状态是否为 pending
if (this.PromiseState !== 'pending') return
// 修改对象状态
this.PromiseState = 'rejected' // 已失败
// 设置对象结果值
this.PromiseResult = data
// 状态失败时执行回调函数
this.callbacks.forEach((item) => {
item.handleReject(data)
})
}
// 捕获 throw
try {
// 同步调用「执行器函数」
executor(resolve, reject)
} catch (error) {
// 修改 promise 对象状态为失败
reject(error)
}
}
// 添加 then 方法
then(handleResolve, handleReject) {
// 返回新的 Promise 对象
return new Promise((resolve, reject) => {
// 封装处理结果回调函数
const callBackResult = (fn) => {
try {
// PromiseResult 传递给回调函数的结果值
const result = fn(this.PromiseResult)
if (result instanceof Promise) {
// 如果是 Promise 类型对象
result.then((v) => {
resolve(v)
}, (e) => {
reject(e)
})
} else {
// 结果状态改为成功
resolve(result)
}
} catch (e) {
reject(e)
}
}
// 根据 PromiseState 调用对应回调函数
if (this.PromiseState === 'fulfilled') {
callBackResult(handleResolve)
}
if (this.PromiseState === 'rejected') {
callBackResult(handleReject)
}
// 等待状态时保存 handleResolve 和 handleReject 函数,后面改变状态时调用
if (this.PromiseState === 'pending') {
this.callbacks.push({
handleResolve: () => {
callBackResult(handleResolve)
},
handleReject: () => {
callBackResult(handleReject)
},
})
}
})
}
// 添加 catch 方法
catch(handleReject) {
return this.then(undefined, handleReject)
}
}
异常穿透
举个例子:
const p = new Promise((resolve, reject) => {
setTimeout(() => {
reject('err')
}, 1000)
})
p
.then((value) => {
console.log(111)
})
.then((value) => {
console.log(222)
})
.catch((err) => {
console.log(err)
})
Chrome 内置的 Promise
输出结果如下:
对比目前手写 Promise
输出结果如下图:
改造代码如下:
点击查看代码
class Promise {
// 构造器
constructor(executor) {
this.PromiseState = 'pending' // 进行中
this.PromiseResult = null // 结果值
this.callbacks = []
// resolve 函数
const resolve = (data) => {
// 判断状态是否为 pending
if (this.PromiseState !== 'pending') return
// 修改对象状态
this.PromiseState = 'fulfilled' // 已成功
// 设置对象结果值
this.PromiseResult = data
// 状态成功时执行回调函数
this.callbacks.forEach((item) => {
item.handleResolve(data)
})
}
// reject 函数
const reject = (data) => {
// 判断状态是否为 pending
if (this.PromiseState !== 'pending') return
// 修改对象状态
this.PromiseState = 'rejected' // 已失败
// 设置对象结果值
this.PromiseResult = data
// 状态失败时执行回调函数
this.callbacks.forEach((item) => {
item.handleReject(data)
})
}
// 捕获 throw
try {
// 同步调用「执行器函数」
executor(resolve, reject)
} catch (error) {
// 修改 promise 对象状态为失败
reject(error)
}
}
// 添加 then 方法
then(handleResolve, handleReject) {
// 判断回调函数参数
if (typeof handleReject !== 'function') {
handleReject = (reason) => {
throw reason
}
}
if (typeof handleResolve !== 'function') {
handleResolve = (value) => value
}
// 返回新的 Promise 对象
return new Promise((resolve, reject) => {
// 封装处理结果回调函数
const callBackResult = (fn) => {
try {
// PromiseResult 传递给回调函数的结果值
const result = fn(this.PromiseResult)
if (result instanceof Promise) {
// 如果是 Promise 类型对象
result.then((v) => {
resolve(v)
}, (e) => {
reject(e)
})
} else {
// 结果状态改为成功
resolve(result)
}
} catch (e) {
reject(e)
}
}
// 根据 PromiseState 调用对应回调函数
if (this.PromiseState === 'fulfilled') {
callBackResult(handleResolve)
}
if (this.PromiseState === 'rejected') {
callBackResult(handleReject)
}
// 等待状态时保存 handleResolve 和 handleReject 函数,后面改变状态时调用
if (this.PromiseState === 'pending') {
this.callbacks.push({
handleResolve: () => {
callBackResult(handleResolve)
},
handleReject: () => {
callBackResult(handleReject)
},
})
}
})
}
// 添加 catch 方法
catch(handleReject) {
return this.then(undefined, handleReject)
}
}
resolve 方法
直接上代码:
class Promise {
// ...省略代码
// 添加 resolve 方法
static resolve(value) {
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then((v) => {
resolve(v)
}, (r) => {
reject(r)
})
} else {
resolve(value)
}
})
}
}
reject 方法
直接上代码:
class Promise {
// ...省略代码
// 添加 reject 方法
static reject(reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
}
all 方法
直接上代码:
class Promise {
// ...省略代码
// 添加 all 方法
static all(promises) {
return new Promise((resolve, reject) => {
let count = 0
const arr = []
for (let i = 0, len = promises.length; i < len; i++) {
promises[i].then((v) => {
// 得知对象的状态是成功
// 每个 promise 对象都成功
count += 1
// 将当前 promise 对象成功的结果 存入到数组中
arr[i] = v
if (count === promises.length) {
resolve(arr)
}
}, (r) => {
reject(r)
})
}
})
}
}
race 方法
直接上代码:
class Promise {
// ...省略代码
// 添加 race 方法
static race(promises) {
return new Promise((resolve, reject) => {
for (let i = 0, len = promises.length; i < len; i++) {
promises[i].then((v) => {
resolve(v)
}, (r) => {
reject(r)
})
}
})
}
}
then 方法回调的异步执行
完整代码如下:
点击查看代码
class Promise {
// 构造器
constructor(executor) {
this.PromiseState = 'pending' // 进行中
this.PromiseResult = null // 结果值
this.callbacks = []
// resolve 函数
const resolve = (data) => {
// 判断状态是否为 pending
if (this.PromiseState !== 'pending') return
// 修改对象状态
this.PromiseState = 'fulfilled' // 已成功
// 设置对象结果值
this.PromiseResult = data
// 状态成功时执行回调函数
setTimeout(() => {
this.callbacks.forEach((item) => {
item.handleResolve(data)
})
})
}
// reject 函数
const reject = (data) => {
// 判断状态是否为 pending
if (this.PromiseState !== 'pending') return
// 修改对象状态
this.PromiseState = 'rejected' // 已失败
// 设置对象结果值
this.PromiseResult = data
// 状态失败时执行回调函数
setTimeout(() => {
this.callbacks.forEach((item) => {
item.handleReject(data)
})
})
}
// 捕获 throw
try {
// 同步调用「执行器函数」
executor(resolve, reject)
} catch (error) {
// 修改 promise 对象状态为失败
reject(error)
}
}
// 添加 then 方法
then(handleResolve, handleReject) {
// 判断回调函数参数
if (typeof handleReject !== 'function') {
handleReject = (reason) => {
throw reason
}
}
if (typeof handleResolve !== 'function') {
handleResolve = (value) => value
}
// 返回新的 Promise 对象
return new Promise((resolve, reject) => {
// 封装处理结果回调函数
const callBackResult = (fn) => {
try {
// PromiseResult 传递给回调函数的结果值
const result = fn(this.PromiseResult)
if (result instanceof Promise) {
// 如果是 Promise 类型对象
result.then((v) => {
resolve(v)
}, (e) => {
reject(e)
})
} else {
// 结果状态改为成功
resolve(result)
}
} catch (e) {
reject(e)
}
}
// 根据 PromiseState 调用对应回调函数
if (this.PromiseState === 'fulfilled') {
setTimeout(() => {
callBackResult(handleResolve)
})
}
if (this.PromiseState === 'rejected') {
setTimeout(() => {
callBackResult(handleReject)
})
}
// 等待状态时保存 handleResolve 和 handleReject 函数,后面改变状态时调用
if (this.PromiseState === 'pending') {
this.callbacks.push({
handleResolve: () => {
callBackResult(handleResolve)
},
handleReject: () => {
callBackResult(handleReject)
},
})
}
})
}
// 添加 catch 方法
catch(handleReject) {
return this.then(undefined, handleReject)
}
// 添加 resolve 方法
static resolve(value) {
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then((v) => {
resolve(v)
}, (r) => {
reject(r)
})
} else {
resolve(value)
}
})
}
// 添加 reject 方法
static reject(reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
// 添加 all 方法
static all(promises) {
return new Promise((resolve, reject) => {
let count = 0
const arr = []
for (let i = 0, len = promises.length; i < len; i++) {
promises[i].then((v) => {
// 得知对象的状态是成功
// 每个 promise 对象都成功
count += 1
// 将当前 promise 对象成功的结果 存入到数组中
arr[i] = v
if (count === promises.length) {
resolve(arr)
}
}, (r) => {
reject(r)
})
}
})
}
// 添加 race 方法
static race(promises) {
return new Promise((resolve, reject) => {
for (let i = 0, len = promises.length; i < len; i++) {
promises[i].then((v) => {
resolve(v)
}, (r) => {
reject(r)
})
}
})
}
}
总结
今天又进步了一点。完。