手寫promise
話不多說,直接上程式碼了
const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTED = 'rejected'
//首先建立三個常量用於表示promise的三個狀態
function MyPromise(fn){
const that = this //在函式體內部首先建立常量that,因為程式碼可能會非同步執行,用於獲取正確的this物件
that.state = PENDING //一開始Promise的狀態是 pending
that.value = null //value 變數用於儲存resolve或者reject中傳入的值
that.resolvedCallbacks = []
that.rejectedCallbacks = []
// resolvedCallbacks和rejectedCallbacks,用於儲存then中的回撥,因為當執行完Promise時狀態可能還是等待中,這時候應該把then中的回撥儲存起來用於狀態改變時使用
function resolve(value) {
if(that.state === PENDING) {
//首先兩個函式都得判斷當前狀態是否為等待中,因為規範規定只有等待態才可以改變狀態
that.state = RESOLVED
that.value = value
//將當前狀態更改為對應狀態,並且將傳入的值賦值給 value
that.resolvedCallbacks.map(cb => cb(that.value))
//遍歷回撥陣列並執行
}
}
function reject(value) {
if(that.state === PENDING){
that.state = REJECTED
that.value = value;
that.rejectedCallbacks.map(cb => cb(that.value));
}
}
try {
fn(resolve, reject)
} catch (e) {
reject(e)
}
//執行promise中傳入的函式,執行傳入的引數並且將之前兩個函式當做引數傳進去
要注意的是,可能執行函式過程中會遇到錯誤,需要捕獲錯誤並且執行 reject 函式
}
複製程式碼
實現then函式
then函式是在Promise構造器中成功狀態下呼叫的resolve方法的回撥。
then函式是可以接收兩個引數的,一個是使用者自定義的成功處理,另一個是使用者自定義的錯誤處理,第二個引數可不傳。
MyPromise.prototype.then = function(onFulfilled, onRejected) {
const that = this
//對傳入的兩個引數做判斷,如果不是函式將其轉為函式
onFulfilled =
typeof onFulfilled === 'function'
? onFulfilled
: v => v
// onFulfilled = v => v
onRejected =
typeof onRejected === 'function'
? onRejected
: r => {
throw r
}
if(that.state === PENDING) {
that.resolvedCallbacks.push(onFulfilled)
that.rejectedCallbacks.push(onRejected)
}
else if(that.state === RESOLVED) {
onFulfilled(that.value)
}
else {
onRejected(that.value)
}
}
new MyPromise((resolve, reject) => {
setTimeout(() => {
// resolve('成功的回撥資料')
reject('失敗')
}, 1000)
}).then((res)=>{
console.log(res)
},(rej)=>{
console.log(rej)
})
複製程式碼
程式碼無註釋 清爽版
const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTED = 'rejected'
function MyPromise(fn){
const that = this
that.state = PENDING
that.value = null
that.resolvedCallbacks = []
that.rejectedCallbacks = []
function resolve(value) {
if(that.state === PENDING) {
that.state = RESOLVED
that.value = value
that.resolvedCallbacks.map(cb => cb(that.value))
}
}
function reject(value) {
if(that.state === PENDING){
that.state = REJECTED
that.value = value;
that.rejectedCallbacks.map(cb => cb(that.value));
}
}
try {
fn(resolve, reject)
} catch (e) {
reject(e)
}
}
MyPromise.prototype.then = function(onFulfilled, onRejected) {
const that = this
//對傳入的兩個引數做判斷,如果不是函式將其轉為函式
onFulfilled =
typeof onFulfilled === 'function'
? onFulfilled
: v => v // onFulfilled = v => v
onRejected =
typeof onRejected === 'function'
? onRejected
: r => {
throw r
}
if(that.state === PENDING) {
that.resolvedCallbacks.push(onFulfilled)
that.rejectedCallbacks.push(onRejected)
}
else if(that.state === RESOLVED) {
onFulfilled(that.value)
}
else {
onRejected(that.value)
}
}
new MyPromise((resolve, reject) => {
setTimeout(() => {
// resolve('成功的回撥資料')
reject('失敗')
}, 1000)
}).then((res)=>{
console.log(res)
},(rej)=>{
console.log(rej)
})
複製程式碼