最近也處於校招面試當中,當然也少不了對 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的完成結果.