1、問題描述
直接為umi的request方法配置攔截器,當(dāng)多條請(qǐng)求同時(shí)觸發(fā)時(shí),發(fā)現(xiàn)同一個(gè)請(qǐng)求會(huì)觸發(fā)攔截器代碼多次執(zhí)行。
import { request?} from '@umijs/max';
export const requestOrigin = (url, opts) => {
? return request(url, {
? ? ?//?umi中的request對(duì)攔截器注入實(shí)現(xiàn)有bug, 多個(gè)接口同時(shí)并發(fā)的情況下會(huì)導(dǎo)致攔截函數(shù)被多次執(zhí)行
? ?? ?requestInterceptors: [requestInterceptor1, requestInterceptor2, requestInterceptor3],
? ? ? responseInterceptors: [responseInterceptor1, responseInterceptor2],
? ? ? ...opts,
? }).then(() => {
? ? // xxx
? }).catch(() => {
? ? // xxx
? });
}
2、解決方案
改用 injectInterceptors() 進(jìn)行攔截器注入。
import {?request?} from '@umijs/max';
export const requestOrigin = (url, opts) => {
? ? injectInterceptors();
? ? return?request(url, {
? ? ? ? ...opts,
? ? ?}).then(() => {
? ? ? ?// xxx
? ? ?}).catch(() => {
? ? ? ?// xxx
? ? ? });
}
injectInterceptors實(shí)現(xiàn)如下:
import { getRequestInstance } from '@umijs/max';
import isArray from 'lodash-es/isArray';
// 注入標(biāo)志器,保證全局僅注入一次
let hasInject = false;
// 請(qǐng)求攔截器
const requestInterceptors = [requestInterceptor1,?requestInterceptor2,?requestInterceptor3];
// 返回?cái)r截器
const responseInterceptors = [responseInterceptor1,?responseInterceptor2];
export function injectInterceptors() {
? if (!hasInject) {
? ? const requestInstance = getRequestInstance();
? ? requestInterceptors.forEach((interceptor: any) => {
? ? ? if (isArray(interceptor)) {
? ? ? ? requestInstance.interceptors.request.use((config) => {
? ? ? ? ? const { url } = config;
? ? ? ? ? if (interceptor[0].length === 2) {
? ? ? ? ? ? const { url: newUrl, options } = interceptor[0](url, config);
? ? ? ? ? ? return { ...options, url: newUrl };
? ? ? ? ? }
? ? ? ? ? return interceptor[0](config);
? ? ? ? }, interceptor[1]);
? ? ? } else {
? ? ? ? requestInstance.interceptors.request.use((config) => {
? ? ? ? ? const { url } = config;
? ? ? ? ? if (interceptor.length === 2) {
? ? ? ? ? ? const { url: newUrl, options } = interceptor(url as string, config) as any;
? ? ? ? ? ? return { ...options, url: newUrl };
? ? ? ? ? }
? ? ? ? ? return interceptor(config);
? ? ? ? });
? ? ? }
? ? });
? ? responseInterceptors.forEach((interceptor) => {
? ? ? isArray(interceptor)
? ? ? ? ? requestInstance.interceptors.response.use(interceptor[0], interceptor[1])
? ? ? ? : requestInstance.interceptors.response.use(interceptor);
? ? });
? }
? hasInject = true;
}
export default injectInterceptors;