api請求時長與請求數據類型的設計

前言

在咱們的業務請求中,有不少時候會針對有不一樣時長的需求策略性設置。這裏針對這個需求進行詳細的展開。前端

針對這種狀況,咱們的timout的通常是根據請求地址來的,因此核心處理技巧即是如何根據不一樣的request地址去設置不一樣的timeout.ios

咱們以前設置的請求時長是十秒,而且是經過create的部分,整個項目只有一個instance的。git

let _axios = axios.create({
  baseURL: apiProxyUrl,
  headers: { 'Content-Type': 'application/json' },
  transformRequest: [transformRequest],
  timeout: 10000 
})複製代碼

那麼既然須要處理request的地址部分,我建議針對長時長的地址單獨一個文件維護,考慮到了如下兩點:github

1 請求地址變多時,能夠更好的定位以及維護
2 須要時,能夠針對不一樣的微服務進行進一步的管理和配置
3 與下面請求時長的策略部分進行解耦複製代碼

主要結果是返回一個指望長時長地址的數組。json

/**
 * @author robin
 * @description maintain all long time api request paths
 */
 
/**
 * 用戶服務長時長地址數組
 */
const userApiPaths = [] 

/**
 * 報表服務長時長地址數組,若是你的微服務地址符合一個規律,能夠這裏進行方法定義並返回
 */
const getTablesApiPaths = ()=>{
    return []
}

export default [
    '/house/list/houseSpaceInHouseSpaceManager'
].concat(userApiPaths).concat(getTablesApiPaths())複製代碼

簡單處理

咱們知道axios自己的request支持攔截器的配置,那麼咱們能夠進行如下簡單的設置。axios

import longTimeApiEnum from './longTimeApiEnum'
// 請求攔截器
_axios.interceptors.request.use((config) => { 
  // 請求時長10分鐘
  const LONG_TIMEOUT = 600000 
  if (longTimeApiEnum.some(url => config.url.includes(url))) {
    config.timeout = LONG_TIMEOUT
  }
  return config
})複製代碼

此方法適用於大部分請求地址沒有規律性,適合用枚舉維護相應地址的。api

策略模式處理

固然若是你的長時長的api地址具備必定的正則可匹配性,也能夠用正則來寫,而且把判斷的部分用策略模式獨立爲一個方法,甚至一個文件。數組

好比下面的例子:微信

// 根據微服務一級地址判斷
function judgeIsLongTimeApi(url){
  const strategy = {
      'user':function(url){
          if(url.includes('/users/data')) return true;
          return false
      },
      'table':function(url){
          if(url.includes('/table')) return true;
          return false
      }
  }

    const firstPath = url.split('/')[1];
    return strategy[firstPath] && strategy[firstPath](firstPath);
    
}

// 使用
const LONG_TIMEOUT = 600000 
  if (judgeIsLongTimeApi(config.url)) {
    config.timeout = LONG_TIMEOUT
  }複製代碼

複雜的類處理

感受上面的方式不夠逼格,或者有時候不是這麼簡單的改一個timeout,還須要改不少配置,好比說baseUrl等等。那麼你須要定義一個class。而後根據你的需求去自定義每一個子類。大概是這樣的:這裏用到了class繼承。app

import axios from 'axios';
class Api{
    constructor(){
        
    }
    nessaryFn(){
        throw Error('必需要實現的函數')
    }
    
    
}

class usualApi extends Api {
    constructor(){
        
    }
    nessaryFn(){
       //codes here
    }
}

class specialApi extends Api {
    constructor(){
        
    }
    nessaryFn(){
       //codes here
    }
}

// 再來一個策略模式 根據不一樣的狀況 ,返回使用不一樣的api實現子類。複製代碼

小結

以上就是所有的關於axios部分的自定義時長作的思考和實踐,已經完整的解決了本身的需求。

其餘問題

請求數據類型或者返回類型很是規時

好比當axios的請求返回類型爲非json類型,須要針對url進行特殊化配置的時候,相應的思路也是如此。

方式一:能夠經過維護關鍵路徑來特殊處理

if (exportXlsEnum.some(url  =>  config.url.includes(url))) {
config.responseType  =  'blob'
}複製代碼

方式二:策略的方式,當符合某種策略,特定的設置某些配置參數以及改變返回結果的校驗,那麼api方法定義時,直接增長傳入策略名稱便可

方式三:若是具備大量的接口具備這樣的特徵,也能夠直接實例化支持該配置的axios實例,調用時直接使用該實例,與常規的axios請求實例區別開。

關於我

  • 我是一名前端Coder,熱愛分享生活與技術中的經驗與心得。
  • 我是一名旅遊愛好者,愛好拍攝旅途中的風景與人物。
  • 我是一名寫做狂人,基本天天都有新文章產出,筆耕不輟。

我的站點

  • GitHub:http://github.com/robinson90
  • codepen:https://codepen.io/robinson90
  • personal blog: http://damobing.com
  • yuque docs: https://www.yuque.com/robinson
  • juejin blog: https://juejin.im/user/5a30ce0c51882561a20a768b

我的微信號與公衆號

微信:csnikey,或者掃碼加我

微信號圖片

達摩空間訂閱號:damo_kongjian,或者掃描下面的二維碼

微信號圖片

相關文章
相關標籤/搜索