重试指的是当加载出错时,有能力重新发起加载组件的请求。
异步组件加载失败后的重试机制,与请求服务端接口失败后的重试机制一样。所以,先来讨论接口请求失败后的重试机制是如何实现的, 为此,需要封装一个fetch函数,用来模拟接口请求:
function fetch(){
return new Promise((resolve,reject) => {
// 请求会在1秒后失败
setTimeout(()=>{
reject('err')
},1000)
})
}
为了实现失败后的重试,需要封装一个load函数,如下面代码所示:
// load函数接收一个onError回调函数
function load(onError){
// 请求接口,得到Promise实例
const p = fetch()
// 捕获错误
return p.catch(err=>{
// 当错误发生时,返回一个新的Promise实例,并调用onError回调
// 同时将retry函数作为onError回调的参数
return new Promise((resolve,reject)=>{
// retry函数,用来执行重试的函数,执行该函数会重新调用load函数并发送请求
const retry = () => resolve(load(onError))
const fail = () => reject(err)
onError(retry, fail)
})
})
}
load函数内部调用fetch函数来发送请求,并得到一个Promise实例,并把该实例的resolve
和reject方法暴露给用户,让用户来决定下一步应该怎么做。这里,将新的Promise实例的resolve和reject分别封装为retry函数和fail函数,并将它们作为onError回调函数的参数。
这样,用户就可以在错误发生时主动选择重试或直接抛出错误。
下面的代码展示了用户时如何进行重试加载的:
// 调用load函数加载资源
load(
// onError回调
(retry) => {
// 失败后重试
retry()
}
).then(res=>{
// 成功
console.log(res)
})
基于这个原理,就可以很容易地将其整合到异步组件的加载流程中,具体实现如下:
function defineAsyncComponent(options){
if(typeof options === 'function'){
options = {
loader: options
}
}
const {loader} = options
let InnerComp = null
// 记录重试次数
let retries = 0
// 封装load函数用来加载异步组件
function load(){
return loader()
.catch((err)=>{
// 如果用户指定了onError回调,则将控制权交给用户
if(options.onError){
return new Promise((resolve,reject) => {
// 重试
const retry = () => {
resolve(load())
retries++
}
// 失败
const fail = () => reject(err)
// 作为onError回调函数的参数,让用户来决定下一步怎么做
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
}
// 调用load函数加载组件
load()
.then(c=>{
InnerComp = c
loaded.value = true
})
.catch((err)=>{
err.value = err
})
.finally(()=>{
loading.value = false
clearTimeout(loadingTimer)
})
// 省略部分代码
}
}
}
到此这篇关于Vue超详细讲解重试机制示例的文章就介绍到这了,更多相关Vue重试机制内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!