国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

記讓一個http請求支持攔截器

Zoom / 1237人閱讀

摘要:但是在使用過程中,發現這個框架自帶的請求庫特別簡單,于是參照手動封裝了一下,使其支持和攔截器。鏈是個數組,然后把請求攔截器放到真正請求的前面,響應后的攔截器放在真請求的后面。

最近想用全js系統的寫一遍前后端學習一下,就創建了一套TODOList項目練手。當前僅寫完了后端demo,前端正在使用vue。并且準備以后再用react和flutter再寫一遍。
此項目
后端demo
前提

在寫練手項目的時候使用了Framework7這個移動端ui框架,因為這個框架的動畫寫的很厲害所以選擇了它。但是在使用過程中,發現這個框架自帶的ajax請求庫特別簡單,于是參照axios手動封裝了一下,使其支持promise和攔截器。

動手

廢話不多說,上代碼
comover.js

import { Request as F7Request } from "framework7";

// 將原始請求對象封裝成Promise對象
function adapter(config) {
    return new Promise(function(resolve, reject) {
        F7Request({
            url: `${config.baseUrl}${config.url}`,
            method: config.method,
            headers: config.headers,
            data: config.data,
            success(data, status, xhr) {
                resolve({
                    data: JSON.parse(data),
                    status: status,
                    config: config,
                    xhr: xhr
                });
            },
            error(xhr, status) {
                let error = new Error(
                    `Request failed with status code ${status}`
                );
                error.xhr = xhr;
                reject(error);
            }
        });
    });
}

// 發送請求
function dispatchRequest(config) {
    return adapter(config).then(
        function onAdapterResolution(response) {
            return response;
        },
        function onAdapterRejection(reason) {
            return Promise.reject(reason);
        }
    );
}

export default class Comeover {
    interceptors = {};
    requestHandlers = [];
    responseHandlers = [];
    config = {};
    constructor(config = ({ baseUrl = "" } = {})) {
        const self = this;

        this.config = { ...config };

        this.interceptors = {
            request: {
                use(fulfilled, rejected) {
                    self.requestHandlers.push({
                        fulfilled,
                        rejected
                    });
                }
            },
            response: {
                use(fulfilled, rejected) {
                    self.responseHandlers.push({
                        fulfilled,
                        rejected
                    });
                }
            }
        };
        
        // ES6中class內方法運行時綁定上下文
        this.request = this.request.bind(this);
    }
    request(config) {
        // 合并默認config和發送請求時的config
        let inconfig = { ...this.config, ...config };
        
        // 創建Promise鏈
        let chain = [dispatchRequest, undefined];
        // 創建初始Promise鏈中傳遞的promise對象
        let promise = Promise.resolve(inconfig);
        
        // 將攔截器注入Promise鏈
        this.requestHandlers.forEach(interceptor => {
            chain.unshift(interceptor.fulfilled, interceptor.rejected);
        });
        this.responseHandlers.forEach(interceptor => {
            chain.push(interceptor.fulfilled, interceptor.rejected);
        });
        
        // 運行Promise鏈
        while (chain.length) {
            promise = promise.then(chain.shift(), chain.shift());
        }
        
        // 返回最終的promise對象
        return promise;
    }
}
使用

這個例子就是在所有請求前后使用nprogress假裝顯示一下請求進度

import Comeover from "./comeover";
import Np from "nprogress";

const baseUrl = process.env.NODE_ENV === "development" ? "" : /* 上線地址 */ "";

const comeover = new Comeover({ baseUrl });

comeover.interceptors.request.use(
    config => {
        Np.start();
        return config;
    },
    error => {
        Np.done();
        return Promise.reject(error);
    }
);
comeover.interceptors.response.use(
    response => {
        Np.done();
        return response;
    },
    error => {
        Np.done();
        return Promise.reject(error);
    }
);

export { request };
發請求
comeover.request({
    url: "/api/login",
    method: "post",
    data: {
        email: this.email,
        password: this.password
    }
})
    .then(({ data }) => {
        this.$store.commit("login", { token: data.message });
        router.back();
    })
    .catch(err => {
        app.dialog.alert("用戶名或密碼錯誤", "登陸失敗");
    });
總結

還可以參照axios繼續封裝多帶帶的get、post等等的方法,這個demo就不寫了。
Promise鏈是個數組,然后把請求攔截器放到真正請求的前面,響應后的攔截器放在真請求的后面。然后以resolve在前,reject在后的順序,成對循環注入到promise.then中。而真正請求的resovereject是寫在dispatchRequest里的,所以dispatchRequest這里沒有reject,要加一個undefined
ES6的實例化方法多帶帶使用的時候this指向會有問題,需要多帶帶處理

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/106911.html

相關文章

  • JS HTTP 請求終極解決方案 - fly.js

    摘要:支持請求響應攔截器。定位與目標的定位是成為請求的終極解決方案。攔截器支持請求響應攔截器,可以通過它在請求發起之前和收到響應數據之后做一些預處理。 Fly.js 是一個功能強大的輕量級的javascript http請求庫,同時支持瀏覽器和node環境,通過適配器,它可以運行在任何具有網絡能力的javascript運行環境;同時fly.js有一些高級的玩法如全局ajax攔截、在web a...

    OpenDigg 評論0 收藏0
  • ★推薦一款適用于SpringBoot項目的輕量級HTTP客戶端框架

    摘要:請求重試攔截器錯誤解碼器在發生請求錯誤包括發生異常或者響應數據不符合預期的時候,錯誤解碼器可將相關信息解碼到自定義異常中。 在SpringBoot項目直接使用okhttp、httpClient或者RestTemplate發起HTTP請求,既繁瑣又不方便統一管理。因此,在這里推薦一個適...

    不知名網友 評論0 收藏0

發表評論

0條評論

Zoom

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<