axios 拦截器实现原理

// 源码 InterceptorManager.js
/**
 * 拦截器的初始化,是一个钩子函数
 * @constructor
 */
function InterceptorManager() {
    this.handlers = [];
}
/**
 * use 方法 将fulfilled和rejected函数加入到拦截器队列,并返回当前拦截器在拦截器队列中的下标作为拦截器ID
 * @param fulfilled
 * @param rejected
 * @param options
 * @returns {number} 
 */
InterceptorManager.prototype.use = function use(fulfilled, rejected, options) {
    this.handlers.push({
        fulfilled: fulfilled,
        rejected: rejected,
        synchronous: options ? options.synchronous : false,
        runWhen: options ? options.runWhen : null
    });
    return this.handlers.length - 1;
};
/**
 * 根据id 删除拦截器队列中对应的值
 * @param id
 */
InterceptorManager.prototype.eject = function eject(id) {
    if (this.handlers[id]) {
        this.handlers[id] = null;
    }
};
/**
 * 重写拦截器的forEach方法
 * @param fn
 */
InterceptorManager.prototype.forEach = function forEach(fn) {
    utils.forEach(this.handlers, function forEachHandler(h) {
        if (h !== null) {
            fn(h);
        }
    });
};
//源码 Axios.js
function Axios(instanceConfig) {
    this.defaults = instanceConfig;
    this.interceptors = {
        request: new InterceptorManager(),
        response: new InterceptorManager()
    };
}
Axios.prototype.request = function request(configOrUrl, config) {
   
    //请求拦截器链
    var requestInterceptorChain = [];
    //同步请求拦截
    var synchronousRequestInterceptors = true;

    this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
        if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) {
            return;
        }

        synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous;
        // 请求拦截器 从下往上执行
        requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected);
    });
    //响应拦截器链
    var responseInterceptorChain = [];
    this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
        // 响应拦截器 从上往下执行
        responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected);
    });

    var promise;
    // 非同步请求拦截器时 错误由下一个拦截器的onRejected函数来执行
    if (!synchronousRequestInterceptors) {
        var chain = [dispatchRequest, undefined];

        Array.prototype.unshift.apply(chain, requestInterceptorChain);
        chain = chain.concat(responseInterceptorChain);

        promise = Promise.resolve(config);
        while (chain.length) {
            promise = promise.then(chain.shift(), chain.shift());
        }

        return promise;
    }

    // 同步请求拦截器时 错误由当前拦截器的onRejected函数来执行
    var newConfig = config;
    while (requestInterceptorChain.length) {
        var onFulfilled = requestInterceptorChain.shift();
        var onRejected = requestInterceptorChain.shift();
        try {
            newConfig = onFulfilled(newConfig);
        } catch (error) {
            onRejected(error);
            break;
        }
    }

    try {
        promise = dispatchRequest(newConfig);
    } catch (error) {
        return Promise.reject(error);
    }

    while (responseInterceptorChain.length) {
        promise = promise.then(responseInterceptorChain.shift(), responseInterceptorChain.shift());
    }

    return promise;
};

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值