完成对请求失败的逻辑补充

此提交包含在:
2021-08-09 23:49:43 +08:00
父節點 45df1f7409
當前提交 1b0e9d3042
共有 2 個檔案被更改,包括 45 行新增10 行删除

查看文件

@@ -3,7 +3,7 @@ import { failed } from './alert';
import qs from 'qs';
import History from './history';
export function get(url) {
export function get(url, evoker) {
return send(
axios.get(url, {
headers: {
@@ -11,10 +11,13 @@ export function get(url) {
"Allow-Control-Allow-Origin": "*"
}
}),
{ fn: () => get(url), identifier: 'get:' + url }
{
fetcher: () => get(url, evoker),
identifier: 'get:' + url + (evoker ? `@${evoker}` : '')
}
);
}
export function post(url, data) {
export function post(url, data, evoker) {
return send(
axios.post(url, qs.stringify(data), {
headers: {
@@ -22,7 +25,10 @@ export function post(url, data) {
"Allow-Control-Allow-Origin": "*"
}
}),
{ fn: () => post(url, data), identifier: 'post:' + url + ' ' + JSON.stringify(data) }
{
fetcher: () => post(url, data, evoker),
identifier: 'post:' + url + (evoker ? `@${evoker}` : '')
}
);
}
@@ -30,9 +36,19 @@ const waitToSend = [];
async function send(xhr, retryConf) {
if (waitToSend.length) {
if (waitToSend.every(retryConfItem => retryConfItem.identifier !== retryConf.identifier))
waitToSend.push(retryConf);
return;
// 等待列表不为空,说明需要等待用户决定是否重试,这也提高了目前请求的成功率
return await new Promise(res => {
if (waitToSend.every(retryConfItem => retryConfItem.identifier !== retryConf.identifier))
waitToSend.push({ ...retryConf, resolver: res });
else
waitToSend
.filter(retryConfItem => retryConfItem.identifier === retryConf.identifier)
.forEach(retryConfItem => {
retryConfItem.resolver({ networkStatus: -2, status: false });
retryConfItem.resolver = res;
});
// 虽然说理论上filter的结果只会有一个,但是还是要forEach一下,因为写起来方便hhhh
});
}
try {
const { data } = await xhr;
@@ -49,11 +65,18 @@ async function send(xhr, retryConf) {
};
if (err?.response?.status === 401) {
History.force('/login');
feedWaitList(failData);
// 若是认证问题导致的错误,则没有必要继续后面等待的请求,且强制跳转后重试可能会导致已卸载的组件被更新
return failData;
}
if (!waitToSend.length) return failData;
waitToSend.push(retryConf);
// 等待列表不为空时弹框要么出现了要么就是在消失的路上,没有办法给予用户点击重试的机会,所以交由外部逻辑处理
// 注意,理论上带有时间戳的请求是不可以重试的,但是这里不做那方面考虑,如果未来有需要,可以自己实现一个刷新时间戳重试的逻辑
if (err.message === 'Network Error')
return await failed('您的设备似乎断网了,请检查网络后重试或刷新', flushWaitList) || failData;
return await failed('您的设备似乎断网了,或者服务器发生了问题,请检查网络后重试或刷新', flushWaitList) || failData;
if (!err?.response?.status)
return await failed('请求发生问题:' + err.message, flushWaitList) || failData;
if (err.response.status === 504)
@@ -63,7 +86,19 @@ async function send(xhr, retryConf) {
}
function flushWaitList() {
let fns = waitToSend.map(item => item.fn);
let fns = waitToSend.map(
conf =>
async () => conf.resolver(await conf.fetcher())
);
waitToSend.splice(0, waitToSend.length);
fns.forEach(fn => fn());
}
function feedWaitList(data) {
let fns = waitToSend.map(
conf =>
() => conf.resolver(data)
);
waitToSend.splice(0, waitToSend.length);
fns.forEach(fn => fn());
}