最近也处于校招面试当中,当然也少不了对 Promise 的话题了。打开 MDN,对着 Promise 的方法,把 then 和 catch 撸了出来。
developer.mozilla.org/zh-CN/docs/… 这是 MDN 中对 Promise 的详细介绍。
属性
function myPromise(executor) {
const self = this
self.status = 'pending'
self.value = undefined
self.onResolvedCallbacks = []
self.onRejectedCallbacks = []
function resolve(value) {
if (self.status === 'pending') {
self.status = 'fulfilled'
self.value = value
self.onResolvedCallbacks.forEach(fn => fn(self.value))
}
}
function reject(error) {
if (self.status === 'pending') {
self.status = 'rejected'
self.value = error
self.onResolvedCallbacks.forEach(fn => fn(self.value))
}
}
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
我们看到 MDN 中对 executor 的介绍:
executor 是带有 resolve 和 reject 两个参数的函数,Promise构造函数执行时立即调用executor 函数。
resolve 和 reject 函数被调用时,分别将promise的状态改为fulfilled(完成)或rejected(失败)
executor 内部通常会执行一些异步操作,一旦完成,可以调用resolve函数来将promise状态改成fulfilled,或者在发生错误时将它的状态改为rejected。
then
myPromise.prototype.then = function (onFulfilled, onRejected) {
// then 传入的参数不是 function,要忽略它
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
onRejected = typeof onRejected === 'function' ? onRejected : reason => {
throw reason
}
const self = this
if (self.status === 'fulfilled') {
return new myPromise((resolve, reject) => {
try {
let x = onFulfilled(self.value)
if (x instanceof myPromise) {
x.then(resolve, reject)
}
resolve(x)
} catch (e) {
reject(e)
}
})
}
if (self.status === 'rejected') {
return new myPromise((resolve, reject) => {
try {
let x = onRejected(self.value)
if (x instanceof myPromise) {
x.then(resolve, reject)
}
resolve(x)
} catch (e) {
reject(e)
}
})
}
// 异步
if (self.status === 'pending') {
return new myPromise((resolve, reject) => {
self.onResolvedCallbacks.push((value) => {
try {
let x = onFulfilled(value)
if (x instanceof myPromise) {
x.then(resolve, reject)
}
resolve(x)
} catch (e) {
reject(e)
}
})
self.onRejectedCallbacks.push((value) => {
try {
let x = onRejected(value)
if (x instanceof myPromise) {
x.then(resolve, reject)
}
resolve(x)
} catch (e) {
reject(e)
}
})
})
}
}
MDN 中 then 的解释:
添加解决(fulfillment)和拒绝(rejection)回调到当前 promise, 返回一个新的 promise, 将以回调的返回值来resolve.
catch
myPromise.prototype.catch = function (onRejected) {
// then 传入的参数不是 function,要忽略它
onRejected = typeof onRejected === 'function' ? onRejected : reason => {
throw reason
}
const self = this
if (self.status === 'fulfilled') {
return new myPromise((resolve, reject) => {
try {
resolve(self.value)
} catch (e) {
reject(e)
}
})
}
if (self.status === 'rejected') {
return new myPromise((resolve, reject) => {
try {
let x = onRejected(self.value)
if (x instanceof myPromise) {
x.then(resolve, reject)
}
resolve(x)
} catch (e) {
reject(e)
}
})
}
// 异步
if (self.status === 'pending') {
return new myPromise((resolve, reject) => {
self.onRejectedCallbacks.push((value) => {
try {
let x = onRejected(value)
if (x instanceof myPromise) {
x.then(resolve, reject)
}
resolve(x)
} catch (e) {
reject(e)
}
})
})
}
}
MDN 中 catch 的解释:
添加一个拒绝(rejection) 回调到当前 promise, 返回一个新的promise。当这个回调函数被调用,新 promise 将以它的返回值来resolve,否则如果当前promise 进入fulfilled状态,则以当前promise的完成结果作为新promise的完成结果.