1. Promise constructor 的初步实现
constructor(executor) {
// 初始化 Promise 实例对象的状态 state 和结果 result
this.state = "pending"
this.result = undefined
// 方法内部实现 resolve 和 reject 两个方法改变 Promise 实例对象的 state 和 result
const resolve = (result) => {
// 当且仅当 Promise 实例对象的状态 state 为 pending 时
// 才能够改变 Promise 实例对象的状态 state 和结果 result
if (this.state === "pending") {
this.state = "fulfilled"
this.result = result
}
}
const reject = (reason) => {
if (this.state === "pending") {
this.state = "rejected"
this.result = reason
}
}
// 如果 executor 执行的过程中出错
// 则直接调用 reject 将错误原因作为 Promise 的 result
try {
executor(resolve, reject)
} catch(e) {
reject(e)
}
}
2. Promise.then 的初步实现
-
对 constructor 中的代码进行修改
constructor(executor) { ... // Promise 实例对象的等待队列 // 当调用 then 方法而 Promise 实例对象的 state 还没有确定时 // 将调用 then 方法时传入的两个参数 onFulfilled 和 onRejected 的异步执行过程加入等待队列 // 待到 Promise 实例对象的 state 确定之后, 全部调用 this.onFulfilledCallbacks = [] this.onRejectedCallbacks = [] const resolve = (result) => { if (this.state === "pending") { this.state = "fulfilled" this.result = result // 当 Promise 实例对象的 state 确定为 fulfilled 时 // 调用 onFulfilledCallbacks 中的所有方法 this.onFulfilledCallbacks.forEach(fn => fn()) } } const reject = (reason) => { if (this.state === "pending") { this.state = "fulfilled" this.result = reason // 当 Promise 实例对象的 state 确定为 rejected 时 // 调用 onRejectedCallbacks 中的所有方法 this.onRejectedCallbacks.forEach(fn => fn()) } } ... } -
then 方法的初步实现
then(onFulfilled, onRejected) { // 当调用 then 方法的 Promise 实例对象的 state 被确定后 // 异步调用 onFulfilled / onRejected 方法 if (this.state === "fulfilled") { setTimeout(() => { onFulfilled(this.result) }) } else if (this.state === "rejected") { setTimeout(() => { onRejected(this.result) }) } // 如果 Promise 实例对象的 state 还没有确定 // 则将异步执行 onFulfilled / onRejected 方法的过程包装成函数添加到 Promise 的等待队列中 else if (this.state === "fulfilled") { this.onFulfilledCallbacks.push(() => { setTimeout(() => { onFulfilled(this.result) }) }) this.onRejecetedCallbacks.push(() => { setTimeout(() => { onRejected(this.result) }) }) } } -
实现 then 方法的链式调用
then(onFulfilled, onRejected) { // 若 onFulfilled 或 onRejected 不是函数 // 则 then 返回的 Promise 实例对象的 state 与 result 和 this 的一样 if (typeof onFulfilled !== "function") { onFulfilled = (result) => result } if (typeof onRejected !== "function") { onRejected = (reason) => {throw reason} } // 构建 then 将要返回的 Promise 实例对象 const promise2 = new Promise((resolve, reject) => { // resolvePromise 方法用于处理 onFulfilled / onRejected 返回的值 x // 如果 x 是 Promise 实例对象, 则继承其 state 与 result // 否则, then 返回的 Promise 实例对象的 result 就是 x // 若是在执行 resolvePromise 的过程中出现 error, 则 result = error if (this.state === "fulfilled") { setTimeout(() => { try { const x = onFulfilled(this.result) resolvePromise(x, promise2, resolve, reject) } catch(e) { reject(e) } }) } else if (this.state === "rejected") { setTimeout(() => { try { const x = onRejected(this.result) resolvePromise(x, promise2, resolve, reject) } catch(e) { reject(e) } }) } else if (this.state === "pending") { this.onFulfilled.push(() => { setTimeout(() => { try { const x = onFulfilled(this.result) resolvePromise(x, promise2, resolve, reject) } catch(e) { reject(e) } }) }) this.onRejected.push(() => { setTimeout(() => { try { const x = onRejected(this.result) resolvePromise(x, promise2, resolve, reject) } catch(e) { reject(e) } }) }) } }) return promise2 } -
resolvePromise 方法的实现
function resolvePromise(x, promise2, resolve, reject) { // 防止出现 let p = promiseObj.then(result => p, reason => p) 的情况 if (x === promise2) { reject(new TypeError("err")) } // 区分 Promise 实例对象的第一步 if (typeof x === "object" && x !== null || typeof x === "function") { // 记录调用次数, 保证仅调用一次 resolve 或 reject let called = false try { const then = x.then // 区分 Promise 实例对象的第二步 if (typeof then === "function") { // 如果 x 是 Promise 实例对象, 则通过 .then 来获取其 state 和 result then.call(x, (result) => { if (called) return called = true // 若 x 的 result 为 Promise 对象, 则递归解开, 直到获取非 Promise 对象 resolvePromise(result, promise2, resolve, reject) }, (reason) => { if (called) return called = true reject(reason) }) } else { // 如果 x 是普通对象或函数 // 则 x 即作为 then 方法返回的 Promise 实例对象的 result resolve(x) } } catch(e) { if (called) return called = true reject(e) } } else { // 如果 x 既不是对象又不是函数 // 则 x 即作为 then 方法返回的 Promise 实例对象的 result resolve(x) } }
3. Promise 的最终实现
function resolvePromise(x, promise2, resolve, reject) {
// 防止出现 let p = promiseObj.then(result => p, reason => p) 的情况
if (x === promise2) {
reject(new TypeError("err"))
}
// 区分 Promise 实例对象的第一步
if (typeof x === "object" && x !== null || typeof x === "function") {
// 记录调用次数, 保证仅调用一次 resolve 或 reject
let called = false
try {
const then = x.then
// 区分 Promise 实例对象的第二步
if (typeof then === "function") {
// 如果 x 是 Promise 实例对象, 则通过 .then 来获取其 state 和 result
then.call(x, (result) => {
if (called) return
called = true
// 若 x 的 result 为 Promise 对象, 则递归解开, 直到获取非 Promise 对象
resolvePromise(result, promise2, resolve, reject)
}, (reason) => {
if (called) return
called = true
reject(reason)
})
} else {
// 如果 x 是普通对象或函数
// 则 x 即作为 then 方法返回的 Promise 实例对象的 result
resolve(x)
}
} catch(e) {
if (called) return
called = true
reject(e)
}
} else {
// 如果 x 既不是对象又不是函数
// 则 x 即作为 then 方法返回的 Promise 实例对象的 result
resolve(x)
}
}
class Promise {
constructor(executor) {
// 初始化 Promise 实例对象的 state 和 result
this.state = "pending"
this.result = undefined
// Promise 实例对象的等待队列
// 当调用 then 方法而 Promise 实例对象的 state 还没有确定时
// 将调用 then 方法时传入的两个参数 onFulfilled 和 onRejected 的异步执行过程加入等待队列
// 待到 Promise 实例对象的 state 确定之后, 全部调用
this.onFulfilledCallbacks = []
this.onRejectedCallbacks = []
const resolve = (result) => {
if (this.state === "pending") {
this.state = "fulfilled"
this.result = result
// 当 Promise 实例对象的 state 确定为 fulfilled 时
// 调用 onFulfilledCallbacks 中的所有方法
this.onFulfilledCallbacks.forEach(fn => fn())
}
}
const reject = (reason) => {
if (this.state === "pending") {
this.state = "rejected"
this.result = reason
// 当 Promise 实例对象的 state 确定为 rejected 时
// 调用 onRejectedCallbacks 中的所有方法
this.onRejectedCallbacks.forEach(fn => fn())
}
}
// 如果传入的方法执行时出错
// 则将出错情况作为 Promise 实例对象的 result
try {
executor(resolve, reject)
} catch(e) {
reject(e)
}
}
then(onFulfilled, onRejected) {
// 若 onFulfilled 或 onRejected 不是函数
// 则 then 返回的 Promise 实例对象的 state 与 result 和 this 的一样
if (typeof onFulfilled !== "function") {
onFulfilled = (result) => result
}
if (typeof onRejected !== "function") {
onRejected = (reason) => {throw reason}
}
// 构建 then 将要返回的 Promise 实例对象
const promise2 = new Promise((resolve, reject) => {
// resolvePromise 方法用于处理 onFulfilled / onRejected 返回的值 x
// 如果 x 是 Promise 实例对象, 则继承其 state 与 result
// 否则, then 返回的 Promise 实例对象的 result 就是 x
// 若是在执行 resolvePromise 的过程中出现 error, 则 result = error
if (this.state === "fulfilled") {
setTimeout(() => {
try {
const x = onFulfilled(this.result)
resolvePromise(x, promise2, resolve, reject)
} catch(e) {
reject(e)
}
})
} else if (this.state === "rejected") {
setTimeout(() => {
try {
const x = onRejected(this.result)
resolvePromise(x, promise2, resolve, reject)
} catch(e) {
reject(e)
}
})
} else if (this.state === "pending") {
this.onFulfilledCallbacks.push(() => {
setTimeout(() => {
try {
const x = onFulfilled(this.result)
resolvePromise(x, promise2, resolve, reject)
} catch(e) {
reject(e)
}
})
})
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onRejected(this.result)
resolvePromise(x, promise2, resolve, reject)
} catch(e) {
reject(e)
}
})
})
}
})
return promise2
}
}
4. Promise.prototype.catch
catch(onRejected) {
return this.then(null, onRejected)
}
5. Promise.prototype.finally
finally(onFinally) {
// 无条件执行 onFinally 方法的同时, 不会使用上一个 Promise 实例对象的 result
// 当 onFinally 方法执行出错时, 返回的 Promise 实例对象的 result 就是错误
// 否则返回的 Promise 实例对象的 result 和 state 相较执行 finally 之前没有改变
return this.then((result) => {
return Promise.resolve(onFinally()).then(() => result)
}, (reason) => {
return Promise.resolve(onFinally()).then(() => {throw reason})
})
}
6. Promise.resolve, Promise.reject
static resolve(result) {
// 如果传递的参数是 Promise 实例, 则直接返回实例
// 否则返回用 Promise 包装后的参数
if (result instanceof Promise) {
return result
} else {
return new Promise((resolve, reject) => {
resolve(result)
})
}
}
static reject(reason) {
if (reason instanceof Promise) {
return reason
} else {
return new Promise((resolve, reject) => {
reject(reason)
})
}
}
7. Promise.all
static all(promises) {
const result = []
let counter = 0
return new Promise((resolve, reject) => {
for (let i = 0, len = promises.length; i < len; i ++) {
// 由于不知道 promises[i] 究竟是不是 Promise 实例
// 故都用 Promise.resolve 包装起来就不用分类讨论了
Promise.resolve(promises[i]).then((res) => {
result[i] = res
if (++ counter === len) {
resolve(result)
}
}, reject)
}
})
}
8. Promise.race
static race(promises) {
return new Promise((resolve, reject) => {
for (let i = 0, len = promises.length; i < len; i ++) {
// 遇到有状态的 Promise 实例或者非 Promise
// 直接改变 race 返回的 Promise 的状态
Promise.resolve(promises[i]).then(resolve, reject)
}
})
}