后端接口返回的时间 和 axios 从 request 到 response 过程的时间 相差巨大?
后端接口返回的时间 和 axios 从 request 到 response 过程的时间 相差巨大?
背景
在用扫码枪扫货品的时候会调接口 每扫一个货品需要请求三个不同接口 在扫前40个货品的时候时间相差不大, 但是一直扫到150+货品的时候 就会出现 时间相差很大的情况
图一是接口返回的时间180ms 图三 从axios request 到 response 前 变成了 800ms
图四 在组件内发起请求到数据返回 时间变成了差不多1800ms 中间没做数据操作 只有增加了请求拦截和响应错误码处理 中间的时间相差这么多 是什么问题导致呢?
// import axios from 'axios'import axios, { AxiosRequestConfig, AxiosResponse, CancelTokenSource } from 'axios';
import baseUrl, { differUrl } from './baseUrl';
import router from '@/router';
import store from '@/store';
import { Message } from 'element-ui';
import { vMessage } from '@rbp/components/base-message';
import { filedMapData, moduleIdMapData } from './config';
import { hideScreenLoading, showScreenLoading } from '@/utils/loading';
import { getCookie, getToken, removeCookie } from '@/utils/auth';
let configChace: any = null; // 存放请求参数,在进入错误时候也关掉loading
const CANCELTTYPE = {
CACHE: 1,
REPEAT: 2
};
interface Request {
onlyKey: string;
url: string;
source: CancelTokenSource;
}
const pendingRequests: Request[] = [];
const config = {
// timeout: 1000 * 60 * 10
// baseURL: baseUrl
};
// eslint-disable-next-line no-unused-vars
const _axios = axios.create(config);
const DELAY = 0;
let timer: any, loadingInstance: any;
const setBaseUrl = (config) => {
const initUrl = config.url;
if (initUrl && initUrl.startsWith('/customize')) {
config.baseURL = differUrl || baseUrl;
config.baseURL = config.baseURL.replace('/manager', '');
config.timeout = 1000 * 60 * 10;
} else if (initUrl && initUrl.startsWith('/report')) {
config.baseURL = (Window as any).config.reportUrl || baseUrl;
config.timeout = 1000 * 60 * 10;
} else if (initUrl && initUrl.startsWith('/new-mf-fac')) {
config.baseURL = localStorage.getItem('JuNiu_WebAddress') || baseUrl;
config.timeout = 1000 * 60 * 10;
} else {
config.baseURL = baseUrl;
config.timeout = 1000 * 60 * 3;
}
};
const setToken = (config) => {
const token = getToken();
const refreshToken = getCookie('refreshToken');
config.headers.Lang = getCookie('language') || 'zh_chs';
if (token) {
config.headers['Authorization'] = token; // 让每个请求携带自定义token 请根据实际情况自行修改
}
if (refreshToken) {
config.headers['RefreshToken'] = refreshToken;
}
};
const setModuleId = (config) => {
const formatRouter: any = (window as any).__POWERED_BY_QIANKUN__ ? (window as any).ymyCustomizeRouter : router;
// 模块 ID 参数 全局传入
// const moduleId = (router as any).history.current.meta.moduleId;
// let moduleId =
// (window as any).Vue2 && (window as any).Vue2.prototype
// ? (window as any).Vue2.prototype._router_.history.current.meta.moduleId
// : (router as any).history.current.meta.moduleId;
let moduleId =
(window as any).Vue2 && (window as any).Vue2.prototype
? (window as any).Vue2.prototype._router_.history.current.meta.moduleId
: formatRouter.history.current.meta.moduleId;
// 对于非/customize接口,替换moduleId为新moduleId
if (config?.url.indexOf('/customize') < 0 && config?.url.indexOf('/role/authority') < 0) {
const obj = moduleIdMapData(config.url, moduleId) || filedMapData(config.url, moduleId);
if (obj?.moduleId) {
config.url = obj.url;
moduleId = obj.moduleId;
if (config.params) {
Object.keys(config.params).forEach((key) => {
if (['baseModuleId', 'moduleId'].includes(key)) {
config.params[key] = obj.moduleId;
}
});
}
}
}
// if (moduleId && config.data) {
// if (config.data && config.data.moduleId) {
// Object.assign(config.data, { moduleId: config.data.moduleId });
// }
if (moduleId && config.data) {
// NetNeedModuleId 接口不需要 moduleId 为 true 则不需要加
if (config.data.NetNeedModuleId) {
delete config.data.NetNeedModuleId;
} else {
if (Object.keys(config.data).indexOf('moduleId') > -1) {
moduleId = config.data.moduleId;
}
Object.assign(config.data, { moduleId: moduleId });
if (typeof config.data.data === 'object') {
if (config?.url.indexOf('/customize') < 0) {
// 对于非/customize接口,将参数中moduleId替换为新moduleId
if (Object.keys(config.data.data).indexOf('moduleId') > -1) {
config.data.data.moduleId = moduleId;
}
} else {
if (Object.keys(config.data.data).indexOf('moduleId') > -1 && config.data.data.moduleId) {
moduleId = config.data.data.moduleId;
}
}
Object.assign(config.data.data, { moduleId: moduleId });
}
}
if (config.data.setModuleIdInHeaders) {
config.headers['moduleId'] = moduleId;
delete config.data.setModuleIdInHeaders;
}
}
};
const setLoading = (config) => {
configChace = config;
// NetNeedModuleId 接口不需要 moduleId 为 true 则不需要加
if (config.method === 'get' && (!config.params || !config.params.NetNeedLoading)) {
config.headers['showLoading'] = true;
showScreenLoading(config.headers);
} else if (['put', 'post'].includes(config.method) && (!config.data || !config.data.NetNeedLoading)) {
config.headers['showLoading'] = true;
showScreenLoading(config.headers);
}
config.params && delete config.params.NetNeedLoading;
config.data && delete config.data.NetNeedLoading;
};
const preventSomeRequest = (config) => {
/**
* 为每一次请求生成一个cancleToken
*/
const source = axios.CancelToken.source();
config.cancelToken = source.token;
/**
* 将之前的重复且未完成的请求全部取消
*/
const params = JSON.stringify(config.params || config.data);
const hits = pendingRequests.filter((item) => item.onlyKey === `${config.baseURL}${config.url}${params}`);
if (hits.length > 0) {
console.error('有重复请求', hits, config);
hits.forEach((item) => item.source.cancel(CANCELTTYPE.REPEAT.toString()));
}
pendingRequests.push({
onlyKey: `${config.baseURL}${config.url}${params}`,
url: `${config.baseURL}${config.url!}`,
source
});
};
_axios.interceptors.request.use(
function (config: AxiosRequestConfig) {
// 全局请求的 loading,当请求 100 ms 后还没返回,才会出现 loading
console.time('_axios.interceptors.request 请求设置header等等信息');
console.time('请求整理到返回中途所需要时间');
config.headers['request-startTime'] = new Date().getTime();
setBaseUrl(config);
setToken(config);
setModuleId(config);
setLoading(config);
// preventSomeRequest(config);
console.timeEnd('_axios.interceptors.request 请求设置header等等信息');
return config;
},
function (error) {
// clearTimeout(timer);
// if (loadingInstance) loadingInstance.close();
// if (config!.headers.showLoading) {
if (configChace.headers['showLoading']) {
hideScreenLoading();
configChace = null;
}
// }
return Promise.reject(error);
}
);
// Add a response interceptor
_axios.interceptors.response.use(
function (response: AxiosResponse) {
// clearTimeout(timer);
// if (loadingInstance) loadingInstance.close();
const headers = response.config.headers;
headers && headers.showLoading && hideScreenLoading();
/**
* code为非20000是抛错 可结合自己业务进行修改
*/
/**
* 不论请求是否成功,
* 将本次完成的请求从请求队列中移除
*/
// 以同样的加密方式(MD5)获取加密字符串
const index = pendingRequests.findIndex((item) => item.url === response.config.url);
//
if (index > -1) {
pendingRequests.splice(index, 1);
}
if (response.config.responseType === 'blob') {
return response.data;
}
const res = response.data;
const FIXCODE = [
0,
10008,
10107,
10112,
10111,
10010,
20001,
30001,
30102,
30103,
30105,
30106,
40100,
40110,
40120,
40121,
40130,
40131,
40140,
40141,
40142,
40160,
40161,
40170,
40180,
50006,
50008,
50009,
50011,
50013,
50014,
50015,
50016,
50017,
50018,
50019,
50020,
50021,
50022,
50024,
50028, // 联营结算模式审核异常code码
50029,
50030,
50025, // 成本结存异常码(未做库存结存的渠道)
50031, // 成本结存异常码(存在以下未审核单据)
50032, // 成本结存异常码(存在本期数量未负的货品)
50033
];
const NO_TOKEN_CODE = [10006]; // 没有权限或者和token失效
const PROGRAM_ERROR_CODE = [500, 10001, 10002]; // 显示错误具体信息弹窗 带复制等功能
console.timeEnd('请求整理到返回中途所需要时间');
if (PROGRAM_ERROR_CODE.includes(res.code)) {
// Infrom({ type: 'error', content: res.msg, detail: res.errorStack, confirmButtonText: '关闭' });
Message({
type: 'error',
message: res.msg,
duration: 3500
});
return Promise.reject('error');
} else if (FIXCODE.includes(res.code)) {
const start = response.config.headers['request-startTime'];
const currentTime = new Date().getTime();
const requestDuration = ((currentTime - start) / 1000).toFixed(2) + 's';
console.log(`%caxios.ts line:288 ${response.config.url} 接口花费时间`, 'requestDuration', requestDuration);
// return res;
return Promise.resolve(res);
} else if (NO_TOKEN_CODE.includes(res.code)) {
//接口登陆失效跳转登录页
vMessage({
type: 'error',
message: res.msg || res.errorStack,
showClose: true,
duration: 3500
});
removeCookie('tempToken');
removeCookie('tempRefreshToken');
store.dispatch('user/resetToken').then(() => {
setTimeout(() => {
window.location.reload();
}, 500);
});
return Promise.reject('loginError');
} else {
Message({
type: 'error',
message: res.msg || res.errorStack,
duration: 3500
});
return Promise.reject('error');
}
},
function (error) {
// clearTimeout(timer);
// if (loadingInstance) loadingInstance.close();
// if (response.config.headers.showLoading) {
// }
// setTimeout(() => {
// hideScreenLoading();
// }, 200);
// 这里是重复请求不弹出
if (error.message !== CANCELTTYPE.REPEAT.toString()) {
if (configChace.headers['showLoading']) {
hideScreenLoading();
configChace = null;
}
// Infrom({ type: 'error', content: error.msg || '请求超时或服务器异常,请检查网络或联系管理员' });
Message({
type: 'error',
message: error.msg || '请求超时或服务器异常,请检查网络或联系管理员'
});
}
return Promise.reject(error);
}
);
export default _axios;
回答:
主要看图一的数据,延迟应该是服务端导致的吧,再延迟出现的时候,api的耗时是多少,请截图一的数据,分析一下
回答:
这段时间涵盖的处理过程太多,尤其是网络过程非常不稳定。要先确定是哪部分造成报时间的大辐增加,如果是网络造成的,那前端不太可能做优化。
如果是想做纯粹的前端监测,从前端可以监测的点开始计时到当前处理不能监测时结束。比如你猜测是拦截引起的效率问题,那你可以只监测这部分处理所花的时间来确认是否是这个问题。
以上是 后端接口返回的时间 和 axios 从 request 到 response 过程的时间 相差巨大? 的全部内容, 来源链接: utcz.com/p/935175.html