Promise
非常好用,去處理非同步問題時,可以鏈式呼叫,解決了回撥地獄的問題。
Promise.resolve
是實現直接建立一個成功態的promise
Promise.reject
是實現直接建立一個失敗態的promise
Promise.all
是處理一組promise
物件的結果,只有當每個promise
都成功時,走.then
方法返回成功陣列,當有一個promise
失敗時,直接走.catch
方法返回失敗原因,all
可以看成旅行乘車,當乘客全都坐上時再走Promise.race
也是處理一組promise
物件的結果,一旦有一個promise
完成,無論成功失敗均標記promise
的完成,race
可以看作是賽跑,一旦有一個完成,就返回結果.catch
是promise
的例項方法,當返回失敗態的promise
時,會走該函式處理異常問題.finally
是promise
的例項方法,無論返回成功失敗,都會走該邏輯,比如當傳送一個請求時展示了loading
元件,無論請求成功或失敗都要關閉該loading
元件,否則使用者將無法操作
下邊介紹每個方法的實現
Promise.resolve
Promise.resolve = function (data) {
// 1 引數是一個 Promise 例項,不做任何修改、原封不動地返回這個例項
if (data instanceOf Promise) {
return data
}
// 2 引數是一個thenable物件,將這個物件轉為 Promise 物件,然後就立即執行thenable物件的then方法。
if (data.then) {
return new Promise((resolve, reject) => {
data.then(resolve, reject)
})
}
// 3 引數不是具有then方法的物件,或根本就不是物件
// 4 不帶有任何引數
return new Promise((resolve) => {
resolve(data)
})
}
複製程式碼
Promise.reject
Promise.reject = function (err) {
return new Promise((_, reject) => {
reject(err)
})
}
複製程式碼
Promise.all
Promise.all = function (promises) {
return new Promise((resolve, reject) => {
let count = promises.length
let result = []
// 遍歷 promises,如果成功,count--,將成功值存入陣列,如果失敗直接 reject,當計數器為0時,resolve結果
promises.forEach((promise, index) => {
Promise.resolve(promise).then(res => {
--count
// 每個 promise 的結果放在其對應位置上
result[index] = res
if (count === 0) {
resolve(result)
}
}).catch(err => {
reject(err)
})
})
})
}
複製程式碼
Promise.race
Promise.race = function (promises) {
return new Promise((resolve, reject) => {
// 直接遍歷 promises,有成功或失敗都立即返回
promises.forEach((promise) => {
// 此處借用 Promise.resolve 將傳入的每一個都 promise化,使其擁有 .then 方法
Promise.resolve(promise).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
})
}
複製程式碼
promise.catch
- 例項方法寫在原型上
class Promise {
// ...
catch(onRejected) {
// 藉助 之前實現的 .then 方法將錯誤資訊傳入該回撥函式
this.then(null, onRejected)
}
// ...
}
複製程式碼
promise.finally
- 例項方法寫在原型上
class Promise {
// ...
// 借用 Promise.resolve方法,使得 callback執行完返回後才會繼續向下,
// 將 promise物件的原資料繼續向下傳遞,
// 失敗資料則需要丟擲供後續catch 使用
finally(callback) {
return this.then(data => {
return Promise.resolve(callback()).then(() => data)
}, err => {
return Promise.resolve(callback()).then(() => {
throw err
})
})
}
// ...
}
複製程式碼
Promise 的實現 傳送門 juejin.im/post/5e0ea8…