Promise
Promise A+ 规范
Promise A+ 规范是对 JavaScript Promise 的一种标准化描述,它定义了 Promise 对象的行为和特性,以确保在不同的 JavaScript 引擎中都能够一致地实现和使用 Promise。
Promise A+ 规范的核心内容包括以下几点:
- Promise 状态
- Promise 有三种状态:Pending(等待中)、Fulfilled(已完成)和Rejected(已拒绝)。
- Promise 的状态只能从 Pending 转变为 Fulfilled 或 Rejected,并且一旦状态转变,就不能再改变。
- Promise 执行
- Promise 的执行函数(通常是一个 executor 函数)在创建 Promise 时立即执行。
- 执行函数接受两个参数:resolve 和 reject。resolve 用于将 Promise 状态转变为 Fulfilled,reject 用于将 Promise 状态转变为 Rejected。
- Promise.then 方法
- Promise 实例提供 then 方法用于注册异步操作完成时的回调函数。
- then 方法接受两个参数:onFulfilled 和 onRejected,分别用于处理异步操作成功和失败时的情况。
- then 方法返回一个新的 Promise 实例,以支持链式调用。
- Promise.catch 方法
- Promise 实例提供 catch 方法用于捕获异步操作失败时的错误。
- catch 方法等效于 then 方法的第二个参数,用于注册处理异步操作失败的回调函数。
- Promise 解决过程
- Promise 解决过程描述了 Promise 的状态转变过程。
- 如果执行函数中调用了 resolve,则将 Promise 的状态转变为 Fulfilled,并传递 resolve 的参数值作为 Promise 的结果。
- 如果执行函数中调用了 reject,则将 Promise 的状态转变为 Rejected,并传递 reject 的参数值作为 Promise 的拒因(reject reason)。
- Promise 链式调用
- Promise 链式调用是指通过 then 方法和 catch 方法串联多个异步操作,以实现更加清晰和可维护的异步编程代码。
Promise A+ 规范的目标是提供一种通用的 Promise 实现标准,使得不同的 JavaScript 引擎都能够支持并遵循相同的 Promise 行为和语义。这样做有助于提高 JavaScript 异步编程的一致性和可移植性,避免了不同实现之间的兼容性问题。
Promise 代码实现
// 声明 MyPromise
class MyPromise {
// 构造函数传入待执行的代码块 executor
constructor(executor) {
// 记录状态
this.state = 'Pending' // Fulfilled、Rejected
// 成功传参
this.value = undefined;
// 异常原因
this.reason = undefined;
// onFulfilledCallbacks 和 onRejectedCallbacks
// 用于存储成功和失败时的回调函数。
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (value) => {
if(this.state !== 'Pending') return
// 更新状态
this.state = 'Fulfilled'
this.value = value
this.onFulfilledCallbacks.forEach(callback => {
callback(value)
})
}
const reject = (reason) => {
if(this.state !== 'Pending') return
// 更新状态
this.state = 'Rejected'
this.reason = reason
this.onRejectedCallbacks.forEach(callback => {
callback(reason)
})
}
try {
// 执行代码块
executor(resolve, reject)
} catch(e) {
reject(e)
}
}
then(onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
if(this.state === 'Pending') {
// 注册阶段
this.onFulfilledCallbacks.push(value => {
// 为了模拟异步操作
// 使用了 setTimeout 将回调函数的执行放入下一个事件循环中,以确保在当前代码块执行完毕后再执行回调函数。
setTimeout(() => {
try {
let result = this.value;
if(typeof onFulfilled === 'function') {
result = onFulfilled(this.value)
}
resolve(result)
} catch(e) {
reject(e)
}
})
})
this.onRejectedCallbacks.push(reason => {
try {
let result = this.reason;
if(typeof onRejected === 'function') {
result = onRejected(this.reason)
}
resolve(result)
} catch(e) {
reject(e)
}
})
} else if(this.state === 'Fulfilled') {
setTimeout(() => {
try {
let result = this.value;
if(typeof onFulfilled === 'function') {
result = onFulfilled(this.value)
}
resolve(result)
} catch(e) {
reject(e)
}
})
} else if(this.state === 'Rejected') {
try {
let result = this.reason;
if(typeof onRejected === 'function') {
result = onRejected(this.reason)
}
} catch(e) {
reject(e)
}
}
})
}
catch (onRejected) {
return this.then(undefined, onRejected);
}
}