axios 源码拦截器解析

2022/3/8 11:14:41

本文主要是介绍axios 源码拦截器解析,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

 查看源码我们发现axios的几种请求方式都是调用request方法,下面一步步分析下。

Axios.prototype.request = function request(configOrUrl, config) {
  /*eslint no-param-reassign:0*/
  // Allow for axios('example/url'[, config]) a la fetch API
  
  if (typeof configOrUrl === 'string') {
      //为了支持axios(url, {config})这种写法
    config = config || {};
    config.url = configOrUrl;
  } else {
       //axios(config)
    config = configOrUrl || {};
  }
    //合并配置
  config = mergeConfig(this.defaults, config);

  // 设置请求方法 默认get方法
  if (config.method) {
    config.method = config.method.toLowerCase();
  } else if (this.defaults.method) {
    config.method = this.defaults.method.toLowerCase();
  } else {
    config.method = 'get';
  }
    //数据类型转换
  var transitional = config.transitional;
   
  if (transitional !== undefined) {
    validator.assertOptions(transitional, {
      silentJSONParsing: validators.transitional(validators.boolean),
      forcedJSONParsing: validators.transitional(validators.boolean),
      clarifyTimeoutError: validators.transitional(validators.boolean)
    }, false);
  }
  // 拦截器      
  var requestInterceptorChain = [];  
  var synchronousRequestInterceptors = true;
   //遍历所有请求拦截器
  this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
       // 对每一个请求拦截器执行以下代码
    if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) {
      return;     // 如果 runWhen 的结果是 false ,那么不执行这个拦截器
    }
     // 判断异步同步
    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;
    // 如果拦截器是异步执行
  if (!synchronousRequestInterceptors) {
      // 初始化一个执行链
    var chain = [dispatchRequest, undefined];
        // 把请求拦截器放在链首
    Array.prototype.unshift.apply(chain, requestInterceptorChain);
        // 把响应拦截器放在链尾
    chain = chain.concat(responseInterceptorChain);
  
    // 添加了拦截器后的chain数组大概会是这样的:
    // [
    //   requestFulfilledFn2, requestRejectedFn2,requestFulfilledFn1, requestRejectedFn1..., 
    //   dispatchRequest, undefined,
    //   responseFulfilledFn1, responseRejectedFn1, responseFulfilledFn2, responseRejectedFn2....,
    // ]
    //初始化化一个promise,给个resolve状态
    promise = Promise.resolve(config);
    while (chain.length) {
              promise = promise.then(chain.shift(), chain.shift());
    }

    return promise;

    // 每次执行while循环,从chain数组里按序取出两项,并分别作为promise.then方法的第一个和第二个参数
    // 按照我们使用InterceptorManager.prototype.use添加拦截器的规则,正好每次添加的就是我们通过InterceptorManager.prototype.use方法添加的成功和失败回调       
     // 第一个请求拦截器的fulfilled函数会接收到promise对象初始化时传入的config对象,而请求拦截器又规定用户写的fulfilled函数必须返回一个config对象,所以通过promise实现链式调用时,每个请求拦截器的fulfilled函数都会接收到一个config对象
    
    // 第一个响应拦截器的fulfilled函数会接受到dispatchRequest请求到的数据(也就是response对象),而响应拦截器又规定用户写的fulfilled函数必须返回一个response对象,所以通过promise实现链式调用时,每个响应拦截器的fulfilled函数都会接收到一个response对象
    
    //通过不断调用promise.then方法形成一个promise链,从而将所有的任务执行串联起来。
  }

   //如果是同步   按照顺序 先指行请求拦截器 再执行 请求操作 请求结果后再执行 响应拦截器
  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;
};

     手动添加几个请求拦截器和响应拦截器 可以更好的理解为什么axios 请求 是按照请求拦截 请求  响应拦截器顺序执行的。

 axios.interceptors.request.use(function request1(config){
     console.log("request1---success")
     return  config
 },function requesterr1(config){
     console.log("request1----error")
     return  config
 })
 
 axios.interceptors.request.use(function request2(config){
      console.log("request2---success")
      return  config
 },function  requesterr2(config){
      console.log("request2----error")
     return  config
 })
 

 axios.interceptors.response.use(function  response1(response){
      console.log("response1---success")
      return  response
 },function responseerr1(response){
      console.log("response1----error")
     return  response
 })
 
 axios.interceptors.response.use(function response2(response){
      console.log("response2---success")
      return  response
 },function responseerr2(response){
      console.log("response2----error")
      return  response
        
 })

 



这篇关于axios 源码拦截器解析的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程