axios的封裝與使用(做了防止多次重復(fù)請求處理)

請求封裝

// ajax.js
import axios from 'axios';
import qs from 'qs'; //參數(shù)編譯

let pending = []; //聲明一個數(shù)組用于存儲每個ajax請求的取消函數(shù)和ajax標(biāo)識
let cancelToken = axios.CancelToken; //引入取消請求方法
//請求完成后取消該請求,從隊列刪除
let removePending = (ever) => {
    for(let p in pending){
        if(pending[p].u === ever.baseURL) { //當(dāng)前請求在隊列中存在時
            pending[p].f(); //執(zhí)行取消操作
            pending.splice(p, 1); //把這條記錄從隊列中移除
        }
    }
}

let baseURL
//項目需要,如果是開發(fā)環(huán)境走本地ip跨域訪問(前提是項目有多環(huán)境配置文件,配置有代理方法)
if (process.env.REACT_APP_ENV === 'development') {
    baseURL = '/api'
} else {
    //非開發(fā)環(huán)境下獲取配置文件的baseurl
    baseURL = process.env.REACT_APP_BASE_URL
}
//請求封裝 method請求方法,全大寫 params參數(shù) url路徑
export const http = (method, params, url, preventRepeat=true,uploadFile=false) => {
    return new Promise((resolve, reject) => {
        const instance = axios.create({
            baseURL: baseURL + url,
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
                //可添加其他公用參數(shù),比如token等
            },
            //設(shè)置超時
            timeout: 50 * 1000
        });
        //默認(rèn)阻止重復(fù)請求
        if (preventRepeat) {
            // request攔截器
            instance.interceptors.request.use(
                config => {
                    removePending(config);//防止雙擊多次觸發(fā)請求
                    config.cancelToken = new cancelToken((c)=>{
                        pending.push({ u: config.baseURL, f: c });
                     });
                    return config;
                },
                err => {
                    return Promise.reject(err);
                }
            );
            //response攔截器
            instance.interceptors.response.use(
                response => {
                    removePending(response.config);
                    return response;
                },
                error => {
                  return Promise.reject(error)
                }
            );
        } else {
            // 攔截器
            instance.interceptors.request.use(
                config => {
                    return config;
                },
                err => {
                    return Promise.reject(err);
                }
            );
            instance.interceptors.response.use(
                response => {
                    return response;
                },
                error => {
                    return Promise.reject(error)
                }
            );
        }
        // 請求(uploadFile為true表示上傳文件binary類型,則參數(shù)不需要編譯)
        instance(
            Object.assign(
                {},
                {method},
                (method === 'POST' || method === 'PUT') ? {data: !uploadFile?qs.stringify(params):params} : {params}
            )
        ).then(response => {
            // success
            if (response.data.code === 200) {
                resolve(response.data);
            }  else {
                resolve(false)
            }
        })
        .catch(error => {
            resolve(false)
        });
    });
}

使用
1.個人習(xí)慣,把所有api寫在一個文件里,默認(rèn)跟ajax.js同級目錄

//api.js
import {http} from './ajax.js'
//示例,默認(rèn)參數(shù)為空,特殊情況有些接口需要循環(huán)請求的,可以設(shè)置參數(shù)preventRepeat為false
//post
export const login = (params={}) => http('POST', params, '/login')
//get
export const getList = (params={}) => http('GET', params, '/list')
export const getDetail = (id,params={}) => http('GET', params, `/detail/${id}`)

2.在需要調(diào)用請求的頁面發(fā)起請求

import {login, getList, getDetail} from 'api.js' //根據(jù)自己項目文件的路徑來寫

//請求
login({name:'張三',password:'123456'})
getList() //沒有參數(shù)的情況
getDetail(1)

//異步處理等待請求完成獲取數(shù)據(jù)
async function getData () {
  const data = await getDetail(1)
  console.log(data)
}
getData()
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容