JS進階系列 --- ajax請求優化

帕尼尼0_0發表於2018-08-05

寫在前面

我們都知道,前端和後端溝通的橋樑是ajax請求介面,前臺通過介面傳給後臺引數,後臺根據引數通過介面返回資料給前臺。
那麼,這些介面要怎麼設計才完美高效呢?

場景一

A頁面有個登入的需求,我們給A頁面造個介面:

doUserLogin: function() {
    this.axios.get('user/login')
    .then(res => {
        if (res.data.status) {
            this.user = res.data.data;
        }
    })
    .catch(error => {
        console.log(error);
    });
},

B頁面有個獲取使用者資訊的需求,我們給B頁面造個介面:

getUserInfo: function() {
    this.axios.get('user/infor')
    .then(res => {
        if (res.data.status) {
            this.user = res.data.data;
        }
    })
    .catch(error => {
        console.log(error);
    });
},

這樣子做,我們在很多頁面都造了介面。
可是這樣子就存在一個問題:我怎麼知道我造了哪些介面,難道一個個頁面找嗎?

場景二

所有介面的資訊我們都在管理中心進行配置

import axios from 'axios';
import store from '../store';

let httpURL = "http://www.xuguobin.club/api/elm/" //這是我伺服器的api介面
let localURL = 'http://localhost/api/elm/';     //這是本地koa2的api介面
axios.defaults.baseURL = localURL;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

export default {
    //獲取使用者資訊
    getUser() {
        return axios.get('user/infor');
    },
    //獲取訂單
    getOrders(orderType) {
        return axios.get('user/order?type=' + orderType);
    },
    //提交訂單
    submitOrder(order) {
        return axios.get('user/submit?order=' + order);
    },
    //確認收貨
    confirmOrder(orderId) {
        return axios.get('user/confirm?orderId=' + orderId);
    },
    //提交評價
    submitRating(rating) {
        return axios.get('user/rating?rating=' + rating);
    },
    //使用者登入
    userLogin(user) {
        return axios.post('user/login',`username=${user.username}&password=${user.password}`);
    },
};

這樣子做,所有介面的資訊一目瞭然。增加一個介面,修改一個介面。直接在管理中心處理就好了。而在每個頁面中使用這些封裝好的介面,例如A頁面有個登入的需求:

doUserLogin: function() {
    this.api.doUserLogin('user/login')
    .then(res => {
        if (res.data.status) {
            this.user = res.data.data;
        }
    })
    .catch(error => {
        console.log(error);
    });
},

這樣子如果是小型專案的話已經可以了,可是如果是一個大型專案的開發的話,介面的數量是上百個的。如果全都放在管理中心也是比較雜亂的。
並且,判斷介面返回的狀態碼和處理錯誤資訊可以提取成公用程式碼,沒有必要每個介面都寫重複程式碼

場景三

我們設定一個大的管理中心,這個管理中心封裝了ajax的一些公共操作

import axios from 'axios'
import setting from './setting'

let httpURL = "http://www.xuguobin.club/api/elm/" //這是我伺服器的api介面
let localURL = 'http://localhost/api/elm/';     //這是本地koa2的api介面

axios.defaults.baseURL = httpURL;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

export default class AxiosCache {
    constructor() {
        this.__config = {}
        this.__setting = setting;
        this.init();
    }

    init() {
        this.doFlushSetting(CACHE_KEY, )
    }

    doFlushSetting(key, conf) {
        if (!key && typeof key !== 'string') {
            return
        }
        this.__config[key] = conf
    }

    /*判斷狀態碼*/
    resultJudge(code) {
        return code
    }

    /*傳送請求資料*/
    sendRequest(key, options) {
        let send = this.__config[this.settingKey][key];
        let self = this;
        let baseURL = send.url;
        send.method == 'get'
            ? options.data && (send.url += options.data)
            : send.data = options.data
        axios(send)
            .then(function (response) {
                send.url = baseURL;
                if (self.resultJudge(response.data.status)) { /*判斷狀態碼*/
                    options.success(response.data.data)
                } else {
                    options.fail /*如果頁面配置了錯誤處理方法就交給該頁面處理,否則統一處理錯誤資訊*/
                        ? options.fail(response.data.data)
                        : self.handleErrorCase(response.data.status)
                }
            }).catch(function (error) {
                self.handleErrorCase(error)
            })
    }

    /*處理錯誤資訊*/
    handleErrorCase(error) {
        if (typeof error == 'Number') {
            console.log(error)
        } else {
            alert(error)
        }
    }
}

同時我們設定很多管理中心繼承自這個大的管理中心
把所有與user相關的介面封裝成USerCache:

import BaseCache from '../base/base'
import config from './config'
const CACHE_KEY = 'user_cache_key' //識別符號

export default class UserCache extends BaseCache {
    constructor () {
        super()
        this.settingKey = CACHE_KEY
    }

    init () {
        this.doFlushSetting(CACHE_KEY, config)
    }

    getUser(options) {
        this.sendRequest('user-getUser',options)
    }

    getOrders(options) {
        this.sendRequest('user-getOrders',options)
    }

    getRatings(options) {
        this.sendRequest('user-getRatings',options)
    }

    submitOrder(options) {
        this.sendRequest('user-submitOrder',options)
    }

    confirmOrder(options) {
        this.sendRequest('user-confirmOrder',options)
    }

    submitRating(options) {
        this.sendRequest('user-submitRating',options)
    }

    userLogin(options) {
        this.sendRequest('user-userLogin',options)
    }
}

另外建立一個檔案config配置訪問引數:

export default {
    'user-getUser': {
        url: 'user/infor',
        method: 'get'
    },
    'user-getOrders': {
        url: 'user/order?type=',
        method: 'get'
    },
    'user-submitOrder': {
        url: 'user/submit?order=',
        method: 'get'
    },
    'user-confirmOrder': {
        url: 'user/confirm?orderId=',
        method: 'get'
    },
    'user-submitRating': {
        url: 'user/rating?rating=',
        method: 'get'
    },
    'user-userLogin': {
        url: 'user/login',
        method: 'post'
    }
}

而如果A頁面有登入的需求的話,只需要這樣寫就可以了:

getUSer: function() {
     this.userCache.getUser({
         success: res => this.user = res
     })
},

相關文章