cancelToken的用法

request.js
这里的逻辑是某个特定的请求多次发起请求,只保留第一个请求,其他重复的请求取消。

import { API_MANAGE } from '@/config/global'
import store from '@/store'
import axios from 'axios'
import { Loading } from 'element-ui'


let loadingInstance

const requestMap = []

/**
 * @description 添加重复的token请求
 */
function addRequest (config, requestId) {
    config.cancelToken = config.cancelToken || new axios.CancelToken((cancel) => {
        requestMap.push({ id: requestId, time: new Date().getTime(), fn: cancel })
    })
}

/**
 * @description 移除请求
 */
function removeRequest (config, requestId) {
    // 只保留第一次请求,后续重复请求均取消
    if (requestMap.length > 1) {
        const removeRequest = requestMap.splice(1, requestMap.length - 1)
        removeRequest.forEach(item => {
            item.fn()
        })
    }
}


// 储存loading实例

const reqInstance= axios.create({
    timeout: 60000,
    headers: {
        'Content-Type': 'application/json;charset=UTF-8'
    }
})

reqInstance.interceptors.request.use(res => {
    // 防止重刷token的接口多次请求
    if (res.url.includes('/xxxApi')) {
        const requestId = Math.random().toString(36).substring(2)
        addRequest(res, requestId)
        removeRequest(res, requestId)
        return res
    } else {
        return res
    }
})

reqInstance.interceptors.response.use(res => {
    requestMap.splice(0, requestMap.length)
    if (loadingInstance) loadingInstance.close()
    if (res.status === 200) {
        const {
            content = null
        } = res.data
        const errorCode = res.data.code || res.data.errorCode
        const msg = res.data.message || res.data.msg

        switch (errorCode) {
            case 0:
                return Promise.resolve(content)
            case 401: {
                const errTip = {
                    msg,
                    errorCode
                }
                return Promise.reject(errTip)
            }
            default: {
                const errTip = {
                    msg,
                    errorCode
                }
                // console.log('errTip>>>', errTip)
                return Promise.reject(errTip)
            }
        }
    }
}, error => {
    requestMap.splice(0, requestMap.length)
    // 取消请求还是要抛出resolve
    if (axios.isCancel(error)) {
        return Promise.resolve(error)
    }
    //关闭loading的样式
    if (loadingInstance) loadingInstance.close()
    const errTips = {
        msg: '',
        code: ''
    }
    if (error.response) {
        const { response } = error
        errTips.msg = response.data.error || response.data.msg || response.statusText || '出错了!'
        errTips.code = response.data.status || response.data.errorCode || response.status || -10001
    } else {
        errTips.msg = error.message
        errTips.code = error.code
    }


    return Promise.reject(errTips)
})

// 默认请求配置,默认携带token
export async function request (param) {
    try {
            if (requestMap.length <= 0) {
                // 判断token是否即将过期
                if (judgeExpiration()) {
                    const tokenResult = await store.dispatch('permissionManage/REFRESH_TOKEN')
                    // 判断token请求是否被取消,如果为否,do something
                    console.log('do something')
                }
            }


        const defaultParam = {
            method: 'post'
        }
        param = { ...defaultParam, ...param }
        const config = {
            baseURL: `${location.origin}/demoRequest`, //配置baseurl
            headers: {
                Authorization: API_MANAGE.getToken(),//配置token
                ...param.headers
            }
        }

        if (param.showLoading) {
            loadingInstance = Loading.service({
                text: '加载中...'
            })
        }
        let requestParam = {
            ...param,
            ...config
        }
        // 根据请求方式,对数据进行处理
        if (param.method.toLowerCase() === 'post') {
            requestParam = {
                ...requestParam,
                data: param?.headers?.['Content-Type'] === 'multipart/form-data'
                    ? param.data
                    : JSON.stringify({
                        ...param.data
                    })
            }
        } else if (param.method.toLowerCase() === 'get') {
            requestParam = {
                ...requestParam,
                params:
                    {
                        ...param.data
                    }
            }
        }

        return reqInstance.request(requestParam)
    } catch (e) {
        if (loadingInstance) loadingInstance.close()
    }
}


// 判断token即将过期(1分钟前)
function judgeExpiration () {
    const expiration = API_MANAGE.getExpirationTime()
    const curTime = Date.parse(new Date())
    return expiration <= curTime + 60000
}

取消请求的另一种方法

![在这里插入图片描述](https://img-blog.csdnimg.cn/fcf6308da1654c1ca941e4b70c3fd16b.png

发现一个比较好用axios中文文档:axios中文文档

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐