Vue超詳細(xì)講解重試機(jī)制示例
重試指的是當(dāng)加載出錯(cuò)時(shí),有能力重新發(fā)起加載組件的請(qǐng)求。
異步組件加載失敗后的重試機(jī)制,與請(qǐng)求服務(wù)端接口失敗后的重試機(jī)制一樣。所以,先來(lái)討論接口請(qǐng)求失敗后的重試機(jī)制是如何實(shí)現(xiàn)的, 為此,需要封裝一個(gè)fetch函數(shù),用來(lái)模擬接口請(qǐng)求:
function fetch(){
return new Promise((resolve,reject) => {
// 請(qǐng)求會(huì)在1秒后失敗
setTimeout(()=>{
reject('err')
},1000)
})
}
為了實(shí)現(xiàn)失敗后的重試,需要封裝一個(gè)load函數(shù),如下面代碼所示:
// load函數(shù)接收一個(gè)onError回調(diào)函數(shù)
function load(onError){
// 請(qǐng)求接口,得到Promise實(shí)例
const p = fetch()
// 捕獲錯(cuò)誤
return p.catch(err=>{
// 當(dāng)錯(cuò)誤發(fā)生時(shí),返回一個(gè)新的Promise實(shí)例,并調(diào)用onError回調(diào)
// 同時(shí)將retry函數(shù)作為onError回調(diào)的參數(shù)
return new Promise((resolve,reject)=>{
// retry函數(shù),用來(lái)執(zhí)行重試的函數(shù),執(zhí)行該函數(shù)會(huì)重新調(diào)用load函數(shù)并發(fā)送請(qǐng)求
const retry = () => resolve(load(onError))
const fail = () => reject(err)
onError(retry, fail)
})
})
}
load函數(shù)內(nèi)部調(diào)用fetch函數(shù)來(lái)發(fā)送請(qǐng)求,并得到一個(gè)Promise實(shí)例,并把該實(shí)例的resolve
和reject方法暴露給用戶(hù),讓用戶(hù)來(lái)決定下一步應(yīng)該怎么做。這里,將新的Promise實(shí)例的resolve和reject分別封裝為retry函數(shù)和fail函數(shù),并將它們作為onError回調(diào)函數(shù)的參數(shù)。
這樣,用戶(hù)就可以在錯(cuò)誤發(fā)生時(shí)主動(dòng)選擇重試或直接拋出錯(cuò)誤。
下面的代碼展示了用戶(hù)時(shí)如何進(jìn)行重試加載的:
// 調(diào)用load函數(shù)加載資源
load(
// onError回調(diào)
(retry) => {
// 失敗后重試
retry()
}
).then(res=>{
// 成功
console.log(res)
})
基于這個(gè)原理,就可以很容易地將其整合到異步組件的加載流程中,具體實(shí)現(xiàn)如下:
function defineAsyncComponent(options){
if(typeof options === 'function'){
options = {
loader: options
}
}
const {loader} = options
let InnerComp = null
// 記錄重試次數(shù)
let retries = 0
// 封裝load函數(shù)用來(lái)加載異步組件
function load(){
return loader()
.catch((err)=>{
// 如果用戶(hù)指定了onError回調(diào),則將控制權(quán)交給用戶(hù)
if(options.onError){
return new Promise((resolve,reject) => {
// 重試
const retry = () => {
resolve(load())
retries++
}
// 失敗
const fail = () => reject(err)
// 作為onError回調(diào)函數(shù)的參數(shù),讓用戶(hù)來(lái)決定下一步怎么做
options.onError(retry, fail, retries)
})
}else{
throw error
}
}
}
return {
name: 'AsyncComponentWrapper',
setup(){
const loaded = ref(false)
const error = shallowRef(null)
const loading = ref(false)
let loadingTimer = null
if(options.delay){
loadingTimer = setTimeout(()=>{
loading.value = true
}, options.delay);
}else{
loading.value = true
}
// 調(diào)用load函數(shù)加載組件
load()
.then(c=>{
InnerComp = c
loaded.value = true
})
.catch((err)=>{
err.value = err
})
.finally(()=>{
loading.value = false
clearTimeout(loadingTimer)
})
// 省略部分代碼
}
}
}
到此這篇關(guān)于Vue超詳細(xì)講解重試機(jī)制示例的文章就介紹到這了,更多相關(guān)Vue重試機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue2.x版本中computed和watch的使用及關(guān)聯(lián)和區(qū)別
這篇文章主要介紹了vue2.x版本中computed和watch的使用及關(guān)聯(lián)和區(qū)別,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,需要的小伙伴可以參考一下2022-07-07
三步搞定:Vue.js調(diào)用Android原生操作
這篇文章主要介紹了三步搞定:Vue.js調(diào)用Android原生操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09
解決vue router使用 history 模式刷新后404問(wèn)題
這篇文章主要介紹了解決vue router使用 history 模式刷新后404問(wèn)題,需要的朋友可以參考下2017-07-07
vue項(xiàng)目中實(shí)現(xiàn)圖片預(yù)覽的公用組件功能
小編接到查看影像的功能需求,根據(jù)需求,多個(gè)組件需要用到查看影像的功能,所以考慮做一個(gè)公用組件,通過(guò)組件傳值的方法將查看影像文件的入?yún)鬟^(guò)去。下面小編通過(guò)實(shí)例代碼給大家分享vue項(xiàng)目中實(shí)現(xiàn)圖片預(yù)覽的公用組件功能,需要的朋友參考下吧2018-10-10
深入淺析Vue不同場(chǎng)景下組件間的數(shù)據(jù)交流
探通過(guò)本篇文章給大家探討不同場(chǎng)景下組件間的數(shù)據(jù)“交流”的Vue實(shí)現(xiàn)方法,感興趣的朋友一起看看吧2017-08-08
Vue.js實(shí)現(xiàn)動(dòng)畫(huà)與過(guò)渡效果的示例代碼
在現(xiàn)代前端開(kāi)發(fā)中,用戶(hù)體驗(yàn)至關(guān)重要,一個(gè)精美的動(dòng)畫(huà)過(guò)渡不僅能提升界面的美觀性,還能讓用戶(hù)在使用時(shí)感受到流暢的交互體驗(yàn),在本文中,我們將深入探討如何在 Vue.js 中實(shí)現(xiàn)動(dòng)畫(huà)與過(guò)渡效果,并提供示例代碼,需要的朋友可以參考下2024-10-10
vue項(xiàng)目實(shí)戰(zhàn)總結(jié)篇
離放假還有1天,今天小編抽空給大家分享前端時(shí)間小編做的vue項(xiàng)目,非常完整,需要的朋友參考下2018-02-02

