有个需求,网络请求超时的情况下进行网络请求的重试,并可以指定重新请求的次数。
这篇文档总结的不错https://github.com/ssttm169/use-axios-well。
思路也很清晰,大致是
axios config
中添加自定义的熟属性,如重新请求的最大次数、请求的间隔时间
interceptors.response
中对网络请求失败的场景进行判断,进行重新请求或其他操作。
需要额外注意,0.19.0有个bug,不支持config中自定义属性,不过旧版本如0.18.1
是支持的。详情追踪issue,之后的版本肯定会修复。
示例如下:
export default function $axios(options) {
return new Promise((resolve, reject) => {
const instance = axios.create({
baseURL: process.env.VUE_APP_BASE_API,
timeout: 1000 * 15,
withCredentials: false
});
instance.interceptors.request.use(
config => {
if (store.getters.token) {
config.headers["th-token"] = store.getters.token;
}
return config;
},
error => {
return Promise.reject(error);
}
);
instance.interceptors.response.use(
res => {
if (res.data.succ) {
return res;
} else {
if (res.data.code === Code.UNAUTHEN || res.data.code === Code.SESSION_TIMOUT) {
MessageBox.confirm("你已被登出,可以取消继续留在该页面,或者重新登录", "确定登出", {
confirmButtonText: "重新登录",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
store.dispatch("LogOut").then(() => {
location.reload();
});
});
} else {
Message({ message: res.data.msg, type: "error", duration: 5000 });
}
return Promise.reject(res);
}
},
err => {
if (err.code === "ECONNABORTED" && err.message.indexOf("timeout") !== -1) {
let config = err.config;
if (!config || !config.retry) {
return Promise.reject(err);
}
config.__retryCount = config.__retryCount || 0;
if (config.__retryCount >= config.retry) {
Message({ message: "请求超时", type: "error", duration: 5000 });
return Promise.reject(err);
}
config.__retryCount += 1;
let backoff = new Promise(function(resolve) {
setTimeout(function() {
resolve();
}, config.retryDelay || 1);
});
return backoff.then(function() {
return instance(config);
});
}
Message({ message: err.message, type: "error", duration: 5000 });
return Promise.reject(err);
}
);
instance(options)
.then(res => {
resolve(res);
})
.catch(error => {
reject(error);
});
});
}
基本调用:
export default function $get(url, timeout, retry, retryDelay) {
let config = {
url: replace.replaceUrl(url),
timeout: (timeout || 30) * 1000,
retry: retry || 0,
retryDelay: retryDelay
};
return new Promise((resolve, reject) => {
request(config)
.then(response => {
resolve(response.data);
})
.catch(error => {
reject(error);
});
});
}
代码见gist https://gist.github.com/tyrad/470d7a3bc4cbdf434c286f9739eaf268