本篇文章主要在于探究 Promise
的实现原理,带领大家一步一步实现一个 Promise
, 不对其用法做说明,如果读者还对Promise的用法不了解,可以查看阮一峰老师的ES6 Promise教程。
接下来,带你一步一步实现一个 Promise
1. Promise
基本结构
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('FULFILLED')
}, 1000)
})
构造函数
Promise
必须接受一个函数作为参数,我们称该函数为handle
,handle
又包含resolve
和reject
两个参数,它们是两个函数。
定义一个判断一个变量是否为函数的方法,后面会用到
// 判断变量否为function
const isFunction = variable => typeof variable === 'function'
首先,我们定义一个名为 MyPromise
的 Class
,它接受一个函数 handle
作为参数
class MyPromise {
constructor (handle) {
if (!isFunction(handle)) {
throw new Error('MyPromise must accept a function as a parameter')
}
}
}
再往下看
2. Promise
状态和值
Promise
对象存在以下三种状态:
Pending(进行中)
Fulfilled(已成功)
Rejected(已失败)
状态只能由
Pending
变为Fulfilled
或由Pending
变为Rejected
,且状态改变之后不会在发生变化,会一直保持这个状态。
Promise
的值是指状态改变时传递给回调函数的值
上文中
handle
函数包含resolve
和reject
两个参数,它们是两个函数,可以用于改变Promise
的状态和传入Promise
的值
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('FULFILLED')
}, 1000)
})
这里 resolve
传入的 "FULFILLED"
就是 Promise
的值
resolve
和 reject
-
resolve
: 将Promise对象的状态从Pending(进行中)
变为Fulfilled(已成功)
-
reject
: 将Promise对象的状态从Pending(进行中)
变为Rejected(已失败)
-
resolve
和reject
都可以传入任意类型的值作为实参,表示Promise
对象成功(Fulfilled)
和失败(Rejected)
的值
了解了 Promise
的状态和值,接下来,我们为 MyPromise
添加状态属性和值
首先定义三个常量,用于标记Promise对象的三种状态
// 定义Promise的三种状态常量
const PENDING = 'PENDING'
const FULFILLED = 'FULFILLED'
const REJECTED = 'REJECTED'
再为
MyPromise
添加状态和值,并添加状态改变的执行逻辑
class MyPromise {
constructor (handle) {
if (!isFunction(handle)) {
throw new Error('MyPromise must accept a function as a parameter')
}
// 添加状态
this._status = PENDING
// 添加状态
this._value = undefined
// 执行handle
try {
handle(this._resolve.bind(this), this._reject.bind(this))
} catch (err) {
this._reject(err)
}
}
// 添加resovle时执行的函数
_resolve (val) {
if (this._status !== PENDING) return
this._status = FULFILLED
this._value = val
}
// 添加reject时执行的函数
_reject (err) {
if (this._status !== PENDING) return
this._status = REJECTED
this._value = err
}
}
这样就实现了 Promise
状态和值的改变。下面说一说 Promise
的核心: then
方法
3. Promise
的 then
方法
Promise
对象的 then
方法接受两个参数:
promise.then(onFulfilled, onRejected)
参数可选
onFulfilled
和 onRejected
都是可选参数。
- 如果
onFulfilled
或onRejected
不是函数,其必须被忽略
onFulfilled
特性
如果 onFulfilled
是函数:
- 当
promise
状态变为成功时必须被调用,其第一个参数为promise
成功状态传入的值(resolve
执行时传入的值) - 在
promise
状态改变前其不可被调用 - 其调用次数不可超过一次
onRejected
特性
如果 onRejected
是函数:
- 当
promise
状态变为失败时必须被调用,其第一个参数为