一i:初始化三种状态:
1;待定状态
const PENDING = 'pending'
2:以实现 成功状态
const FULFILLED = 'fulfilled'
3:失败状态
const REJECTED = 'rejected'
二:实现reject()和resolve()
/ 以构造函数的形式实现
class MyPromise {
constructor(executor) {
// 利用 try/catch 捕获错误
try {
executor(this.resolve, this.reject)
} catch (error) {
this.reject(error)
}
}
// 定义 Promise 初始状态为 PENDING
status = PENDING
// resolve 后返回的数据
data = undefined
// reject 后返回的原因
reason = undefined
// 成功
resolve = data => {
// 一旦状态改变,就不能再变
if (this.status !== PENDING) return
// 更改状态
this.status = FULFILLED
// 保存数据
this.data = data
}
// 失败
reject = reason => {
// 一旦状态改变,就不能再变
if (this.status !== PENDING) return
// 更改状态
this.status = REJECTED
// 保存原因
this.reason = reason
}
}
三:实现then
.then() 方法是 Promise 的核心之一,异步操作的成功或失败,都可以通过
.then() 添加的回调函数进行处理。并且它将继续返回一个 Promise 对象,这样可以通过多次调用
.then() 添加多个回调函数,它们会按照插入的顺序执行,形成链式调用(chaining)。
class MyPromise {
/ resolve 的回调函数列表
successCallback = []
// reject 的回调函数列表
failureCallback = []
// 成功
resolve = data => {
// 依次调用成功回调
while (this.successCallback.length) {
this.successCallback.shift()(this.data)
}
}
// 失败
reject = reason => {
// 依次调用失败回调
while (this.failureCallback.length) {
this.failureCallback.shift()(this.reason)
}
}
// .then():处理 resolve 和 reject
then(onResolved = data => data /*设置默认的成功回调 */, onRejected) {
// 创建一个新的 Promise 并 return,以供链式调用
let promise = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED) {
// 转换为 异步执行,用来获取 新的 promise
setTimeout(() => {
try {
let value = onResolved(this.data)
// 判断返回值是普通值还是 Promise
resolvePromise(promise, value, resolve, reject)
} catch (error) {
reject(error)
}
}, 0)
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
let value = onRejected(this.reason)
resolvePromise(promise, value, resolve, reject)
} catch (error) {
reject(error)
}
}, 0)
} else {
// 将回调函数存入数组中等待被执行
this.successCallback.push(() => {
setTimeout(() => {
try {
let value = onResolved(this.data)
resolvePromise(promise, value, resolve, reject)
} catch (error) {
reject(error)
}
}, 0)
})
// 将回调函数存入数组中等待被执行
this.failureCallback.push(() => {
setTimeout(() => {
try {
let value = onRejected(this.reason)
resolvePromise(promise, value, resolve, reject)
} catch (error) {
reject(error)
}
}, 0)
})
}
})
return promise
}
}
第四步:实现 .catch()
实现 .then() 之后,.catch() 就会简单很多。事实上,.catch() 只是没有给 fulfilled 状态预留参数位置的 .then() 而已,所以这里我们直接返回一个没有成功回调函数的 .then() 即可。
class MyPromise {
// .catch()
catch(onRejected) {
// 事实上 .catch() 只是没有给 fulfilled 状态预留参数位置的 .then()
return this.then(undefined, onRejected)
}
}
第五步:实现 .finally()
有时候我们会在成功或失败执行相同的函数,为了避免了同样的语句需要在中各写一次的情况,所以有了.finally() 方法。也就是说,在 Promise 的结果无论是 fulfilled 或者是 rejected,.finally() 都会执行指定的回调函数。但区别于 .then() 和 .catch(),.finally() 的回调函数中不接收任何参数
class MyPromise {
// .finally()
finally(callback) {
return this.then(
data => {
return MyPromise.resolve(callback().then(() => data))
},
err => {
return MyPromise.resolve(callback()).then(() => {
throw err
})
}
)
}
}
第六步:实现 Promise.all()
Promise.all() 方法主要用于集合多个 Promise 的返回结果。
class MyPromise {
// Promise.all()
static all(iterable) {
// 记录执行次数
let times = 0
// 保存执行结果
let result = []
// Promise.all() 会返回一个 Promise
return new MyPromise((resolve, reject) => {
// 记录结果
function addData(key, value) {
times++
result[key] = value
times === iterable.length && resolve(result)
}
// 依次执行,然后将结果保存到数组中
iterable.forEach((element, index) => {
// 判断元素是否为 Promise 对象
element instanceof MyPromise
? element.then(
data => addData(index, data),
err => reject(err) // 任何一个 Promise 对象的 reject 被执行都会立即 reject()
)
: addData(index, element) // 非 promise 的元素将被直接放在返回数组中
})
})
}
}
第七步:实现 Promise.resolve(
Promise.resolve() 方法返回一个以给定值解析后的 Promise 对象。
class MyPromise {
// Promise.resolve()
static resolve(value) {
// 返回一个以给定值解析后的 Promise 对象
return value instanceof MyPromise
? value
: new MyPromise(resolve => resolve(value))
}
}
第八步:实现 Promise.reject()
Promise.reject() 方法返回一个带有拒绝原因的 Promise 对象。
class MyPromise {
// Promise.reject()
static reject(error) {
return new MyPromise((resolve, reject) => {
reject(error)
})
}
}