Vue超详细讲解重试机制示例
loyd3 人气:0重试指的是当加载出错时,有能力重新发起加载组件的请求。
异步组件加载失败后的重试机制,与请求服务端接口失败后的重试机制一样。所以,先来讨论接口请求失败后的重试机制是如何实现的, 为此,需要封装一个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) }) // 省略部分代码 } } }
加载全部内容