1

一、配置 axios

安装依赖

npm i axios

新建 src/api/request.ts

// src/api/request.ts
import axios from 'axios';

const service = axios.create({
    withCredentials: true,
    baseURL: '',
    timeout: 60 * 1000,
});

// request 拦截器
service.interceptors.request.use(
    (config) => config,
    (error) => Promise.reject(error)
);

// response 拦截器
service.interceptors.response.use(
    (response) => {
        if (response.status === 200) {
            const { data, responseCode, responseMsg } = response.data;

            if (responseCode === '000000') {
                return data;
            }
            return Promise.reject(responseMsg);
        }

        return Promise.reject(response);
    },
    (error) => Promise.reject(error)
);

export default service;

新建 src/api/todo-service.ts

// src/api/todo-service.ts
import request from './request';

export interface GetTodoListParams {
    pageSize: number;
    current: number;
    keyword: string;
}

export interface TodoItem {
    id: string;
    text: string;
}

export const getTodoList = async (data: GetTodoListParams) => {
    return request({
        method: 'post',
        url: '/todo-service/getTodoList.do',
        data,
    });
};

修改 vite.config.ts,配置服务代理

// vite.config.ts
export default () => { 
    const env = loadEnv(mode, process.cwd());
    return defineConfig({
        // code
        server: {
            host: true,
            port: 4000,
            proxy: {
                '/todo-service': {
                    target: 'http://aaa.com/todo-service',
                    changeOrigin: true,
                },
            },
        },
    })
}

调用 axios 请求

import { getTodoList } from '@/api/todo-service'

getTodoList({
    pageSize: 10,
    currentPage: 1
})
    .then(res => { })
    .catch(error => { })

一个简单的axios配置基本完成。

二、问题记录

1,使用 await/async 代替 Promise 链式调用

npm i await-to-js

修改 src/api/request.ts

// src/api/request.ts
import to from 'await-to-js'; // 新增

// 删除
// export default service;

// 新增
export default async function request<T>(params: any) {
    return await to<T, any>(service(params));
}

修改 src/api/todo-service.ts

// src/api/todo-service.ts

export const getTodoList = async (data: GetTodoListParams) => {
    return request<TodoItem[]>({
        method: 'post',
        url: '/todo-service/getTodoList.do',
        data,
    });
}

使用

import { getTodoList } from '@/api/todo-service'

const [err, res] = await getTodoList({
    pageSize: 10,
    currentPage: 1
})

2,取消已发送的请求

有些场景下,请求发送成功后,接口返回响应数据前再次发送了请求,需要取消第一次发送的请求。

解决方案:使用 axios.CancelToken 取消请求
修改src/api/request.ts

// src/api/request.ts
const cancelableRequests: string[] = ['/todo-service/getTodoList.do'];
const pending = new Map();
let { CancelToken } = axios;
const removePending = (url: string) => {
    const cancel = pending.get(url);
    if (cancel) {
        cancel();
        pending.delete(url);
    }
};

// request拦截器
service.interceptors.request.use(
    (config) => {
        const { url } = config;
        if (url && cancelableRequests.includes(url)) {
            // 取消之前的请求
            removePending(url);
            // 设置当前请求的cancel方法
            config.cancelToken = new CancelToken((cancel) => {
                pending.set(url, cancel);
            });
        }
        return config;
    },
    (error) => Promise.reject(error)
);

// response拦截器
service.interceptors.response.use(
    (response) => {
        // code
    },
    (error) => {
        // 单独处理取消请求的错误信息
        if(error.name === "CanceledError") {
            // code
        }
        return Promise.reject(error)
    }
)

似曾相识
169 声望7 粉丝