current position:Home>[source code] Axios

[source code] Axios

2021-08-25 09:34:44 woow_ wu7



  • The following figure for 2020/01/05 Redraw during review
  • The following figure for 2020/01/05 Redraw during review
  • The following figure for 2021/02/07 Then review the request process

Navigation

[[ thorough 01] Execution context ](https://juejin.im/post/684490...)
[[ thorough 02] Prototype chain ](https://juejin.im/post/684490...)
[[ thorough 03] Inherit ](https://juejin.im/post/684490...)
[[ thorough 04] The event loop ](https://juejin.im/post/684490...)
[[ thorough 05] currying Partial function Function memory ](https://juejin.im/post/684490...)
[[ thorough 06] Implicit conversion and Operator ](https://juejin.im/post/684490...)
[[ thorough 07] Browser caching mechanism (http Caching mechanisms )](https://juejin.im/post/684490...)
[[ thorough 08] Front end security ](https://juejin.im/post/684490...)
[[ thorough 09] Depth copy ](https://juejin.im/post/684490...)
[[ thorough 10] Debounce Throttle](https://juejin.im/post/684490...)
[[ thorough 11] Front-end routing ](https://juejin.im/post/684490...)
[[ thorough 12] Front-end modularization ](https://juejin.im/post/684490...)
[[ thorough 13] Observer mode Publish subscribe mode Two way data binding ](https://juejin.im/post/684490...)
[[ thorough 14] canvas](https://juejin.im/post/684490...)
[[ thorough 15] webSocket](https://juejin.im/post/684490...)
[[ thorough 16] webpack](https://juejin.im/post/684490...)
[[ thorough 17] http and https](https://juejin.im/post/684490...)
[[ thorough 18] CSS-interview](https://juejin.im/post/684490...)
[[ thorough 19] Handwriting Promise](https://juejin.im/post/684490...)
[[ thorough 20] Handwritten functions ](https://juejin.im/post/684490...)

[[react] Hooks](https://juejin.im/post/684490...)

[[ Deploy 01] Nginx](https://juejin.im/post/684490...)
[[ Deploy 02] Docker Deploy vue project ](https://juejin.im/post/684490...)
[[ Deploy 03] gitlab-CI](https://juejin.im/post/684490...)

[[ Source code -webpack01- Pre knowledge ] AST Abstract syntax tree ](https://juejin.im/post/684490...)
[[ Source code -webpack02- Pre knowledge ] Tapable](https://juejin.im/post/684490...)
[[ Source code -webpack03] Handwriting webpack - compiler Simple compilation process ](https://juejin.im/post/684490...)
[[ Source code ] Redux React-Redux01](https://juejin.im/post/684490...)
[[ Source code ] axios ](https://juejin.im/post/684490...)
[[ Source code ] vuex ](https://juejin.im/post/684490...)
[[ Source code -vue01] data Response type and Initialize rendering ](https://juejin.im/post/684490...)
[[ Source code -vue02] computed Response type - initialization , visit , The update process ](https://juejin.im/post/684490...)
[[ Source code -vue03] watch Listening properties - Initialization and update ](https://juejin.im/post/684490...)
[[ Source code -vue04] Vue.set and vm.$set ](https://juejin.im/post/684490...)
[[ Source code -vue05] Vue.extend ](https://juejin.im/post/684490...)

[[ Source code -vue06] Vue.nextTick and vm.$nextTick ](https://juejin.im/post/684790...)

Pre knowledge

Some words

Interceptors: Interceptor 
bother: annoyance 
ties: system , bundle , necktie , contact 

immutably: constant 
precedence: Priority 

determine: determine , find out 
( Determine if a value is a FormData  Determine whether the value is FormDate type  )

inherit: Inherit 

<font color=DarkOrchid>axios Cancel request method 1 - axios.CancelToken.source()</font>

  • const source = axios.CancelToken.source() Factory function

    • source.token
    • source.cancel(message)
    • source = {token: cancelToken object , cancel: Cancel function }
  • axios.isCancel
  • Be careful

    • Every time you request source It can't be the same source object , If it's the same source object , After the cancellation request , The request cannot be sent again

      (1)  After canceling the request , The request cannot be sent again 
      const CancelToken = axios.CancelToken;
      const source = CancelToken.source(); // ----------------------------- source Factory function 
      
      axios.get('/user/12345', {
      cancelToken: source.token 
      // ------------------------------ token [2021/01/04 to update ]
      // ------------------------------ token, After canceling the request here , You can't send the request again , Because it's the same source object , Is the same token
      // ------------------------------  The solution is to  source  In each request method 
      }).catch(function (thrown) {
      if (axios.isCancel(thrown)) {
      console.log('Request canceled', thrown.message);
      } else {
      // handle error
      }
      });
      
      //  Cancel the request 
      source.cancel('Operation canceled by the user.'); // ----------------- cancel function 

      2021/01/04 When reviewing, I found the above request , You cannot send the request again after canceling the request , Use the following methods to solve

      (2)  After canceling the request , You can send the request again 
      import React, { useState } from 'react'
      import axios from 'axios'
      
      const AxiosCancelToken = () => {
      const [cancalFn1, setCancalFn1] = useState(() => { }) as any
      const [links] = useState([
      {
        name: 'axios Source code  - axios Source code analysis warehouse ',
        url: 'https://github.com/woow-wu7/7-react-admin-ts/tree/master/src/SOURCE-CODE-ANALYSIS/AXIOS'
      },
      {
        name: 'axios Source code  -  My Nuggets blog ',
        url: 'https://juejin.cn/post/6844904147532120072'
      },
      ])
      const renderLinks = () => links.map(({ name, url }) => <div key={name}><a href={url} target="blank">{name}</a></div>)
      // axios Cancel the request 
      //  Method 1 
      // axios.CancelToken.source.token
      // axios.CancelToken.source.cancel
      //  Be careful : Set up a source It can't be the same source, If it's the same source Words , After canceling the request, you can't re request again 
      const handleRequest = async () => {
      const source = axios.CancelToken.source()
      setCancalFn1(() => source.cancel)
      await new Promise(resolve => {
        setTimeout(() => {
          console.log(' Time delay 2s perform ')
          return resolve('success')
        }, 2000)
      })
      await axios({
        url: '/API/pic.php',
        method: 'get',
        cancelToken: source.token
      }).catch(err => {
        if (axios.isCancel(err)) {
          console.log('object :>> ', err.message);
        } else {
          console.log('error')
        }
      })
      }
      const cancelRequest = () => {
      cancalFn1(' The request was cancelled ')
      }
      return (
      <div className="axios-cancel-token">
        <p>Axios - CancelToken test </p><br />
      
        <div> Please open the browser debugging panel mode </div>
        <button onClick={handleRequest}> Click send request 1 -  Every request uses promise Time delay 2s simulation </button><br />
        <button onClick={cancelRequest}> Click on  -  Cancel request method 1 -  Factory function source</button><br />
        <div>
          {renderLinks()}
        </div>
      </div>
      )
      }
      
      export default AxiosCancelToken

<font color=DarkOrchid>axios Cancel request method 2 - new axios.CancelToken()</font>

  • const cancalTokenInstance = new axios.CancelToken(c => cancel = c)

    • The generated is cancalToken example
    • Parameter is a callback function , The parameters of the callback function are cancel() function
    • Pay attention to the incoming CancelToken(c => cancel = c) It's a cancel function , This cancel The function takes its own arguments c Assigned to cancel Variable ,c It's also a function , namely cancel function
    const CancelToken = axios.CancelToken;
    let cancel;
    
    axios.get('/user/12345', {
    cancelToken: new CancelToken(function executor(c) {
      // An executor function receives a cancel function as a parameter
      cancel = c;
    })
    });
    
    // cancel the request
    cancel();

    2020/01/06 Review the example of the second cancellation request , There is a hole in it , Look at the comments in the following code

  • 1. By direct new axios.CancelToken()
  • 2. Instead of calling CancelToken Static method of source() Generate {token, cancel}

     const handleRequest2 = async () => {
      const token = new axios.CancelToken(c => setCancelFn2(() => c)) //  take c Assign a value to state
      await new Promise(resolve => {
        setTimeout(() => {
          console.log(' Time delay 2s perform ')
          return resolve('success')
        }, 2000)
      })
      await axios({
        url: '/API/pic.php',
        method: 'get',
        cancelToken: token,
        // cancelToken: new axios.CancelToken(c => setCancelFn2(() => c)) //  This kind of writing is not allowed !!!!!!!!!!!!!!!!!!!!
      }).catch(err => {
        if (axios.isCancel(err)) {
          console.log('object :>> ', err.message);
        } else {
          console.log('error')
        }
      })
    }
    const cancelRequest2 = () => {
      console.log(cancelFn2);
      cancelFn2(' The request was cancelled ') // state
    }

<font color=DarkOrchid>axios Cancel the request - example 1</font>

<template>
  <div class="cancal-request">
    <div>cancel-request</div>
    <div @click="getData"> request : Click Get request data  - new CancelToken() Method </div>
    <div @click="cancalRequest"> Cancel the request : Click Cancel to get the requested data </div>

    <div @click="getData2"> request : Click Get request data  - source() Factory function mode </div>
    <div @click="cancalRequest2"> Cancel the request : Click Cancel to get the requested data </div>

    <div>{{data.responseTime}}</div>
  </div>
</template>

<script>
import axios from "axios";

export default {
  name: "CancelRequest",
  data() {
    return {
      cancelFn: null,
      data: {
        responseTime: null
      },
      source: null
    };
  },
  methods: {
    getData() {
      axios({
        baseURL: "/api",
        timeout: 2000,
        url: "/cancel-request",
        method: "get",
        cancelToken: new axios.CancelToken(c => {
          // new axios.CancelToken() 
            //  Return value   =>  It's a  cancelToken
            //  Parameters  =>  Is a callback function , The parameters of the callback function are  cancel()  function 
          this.cancelFn = c;
        })
      }).then(res => {
        console.log(res, "res-data");
        this.data = res.data
      });
    },
    cancalRequest() {
      if (this.cancelFn) {
        this.cancelFn(' With  new axios.CancelToken(c => this.cancelFn = c)  Way to cancel the request ');
        //  Cancel the request 
      }
    },
    getData2() {
      this.source = axios.CancelToken.source();
      //  utilize  axios.CancelToken.source()  The factory function generates an object 
        // source = {token: cancelToken object , cancel:  Cancel function }
        // source.token
        // source.cancel
      axios({
        baseURL: "/api",
        timeout: 2000,
        url: "/cancel-request",
        method: "get",
        cancelToken: this.source.token // token
      }).then(res => {
        console.log(res, "res-data");
        this.data = res.data
      });
    },
    cancalRequest2() {
      if (this.source.cancel) {
        this.source.cancel(' With  source() Factory function method   Cancel the request ');  // cancel
      }
    }
  }
};
</script>

<font color=DarkOrchid>axios Cancel the request - example 2 - mixin The way </font>

mixin/index.js

import axios from 'axios';

export const mixinCancelToken = {
  data() {
    return {
      cancelToken: null, // ----------------------------------- cancelToken
      cancel: null // ----------------------------------------- cacel Cancel function 
    }
  },
  created() {
    this.cancelToken = new axios.CancelToken(c => { // -------- cancelToken assignment 
      this.cancel = c // -------------------------------------- cancel Function assignment 
    })
  },
  beforeDestroy() {
    if (this.cancel) {
      this.cancel(` Cancel the request mixin The way `) // ---------------------  When the component is uninstalled , Cancel the request 
    }
  }
}
 In the business component 

<template>
  <div class="cancal-request-component">
    <div>cancel-request-component</div>
    <div @click="getData"> request : Click Get request data  - mixin The way </div>
    <div @click="cancalRequest"> Cancel the request : Click Cancel to get the requested data  - - mixin The way </div>
  </div>
</template>

<script>
import { mixinCancelToken } from "../mixin";
import axios from "axios";

export default {
  name: "CancelRequestComponent",
  mixins: [mixinCancelToken], // -----------------------------------------  Inject mixin
  data() {
    return {};
  },
  mounted() {},
  methods: {
    getData() {
      axios({
        baseURL: "/api",
        timeout: 2000,
        url: "/cancel-request",
        method: "get",
        cancelToken: this.cancelToken // ---------------------------------  from mixin In order to get cancelToken
      }).then(res => {
        console.log(res, "res-data");
        this.data = res.data
      });
    },
    cancalRequest() {
      if (this.cancel) {
        this.cancel(' Cancel the request mixin The way ') // -------------------------------  from mixin In order to get cancel
      }
    }
  }
};
</script>


<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="stylus">
.cancal-request-component {
  background: yellow;
}
</style>

axios Use of interceptors

import axios from 'axios'

const baseURL = '/api'
const headers = {
    'Content-Type': 'application/json'
}

const axiosInstance = axios.create({
    baseURL,
    headers,
    timeout: 1000,
})
console.log(typeof axiosInstance, 'axios.create({...}) Returns a function ')

//  Request to intercept 
// 1. Axios() There is... In the constructor this.interceptors object 
// 2. interceptors There are two properties on the object 
    // request attribute , Is an instance object , Inherited... On the prototype object  use eject forEach  Such method 
    // response attribute , Is an instance object , Inherited... On the prototype object  use eject forEach  Such method 
axiosInstance.interceptors.request.use(config => {
    return config
}, error => {
    return Promise.reject(error)
})

//  The response to intercept 
axiosInstance.interceptors.response.use(response => {
    return response
}, error => {
    return Promise.reject(error)
})

export const baseApi = async ({ url, method, paramsOrData }) => {
    try {
        const paramsOrDataKey = method.match(/get/i) ? 'params' : 'data';
        const res = await axios.request({
            url,
            method,
            [paramsOrDataKey]: paramsOrData
        })
        return res
    } catch (err) {
        throw new Error(err)
    }

}

export default axiosInstance

XMLHttpRequest

  • How to get response???

    • xhr.response
    • xhr.responseText
    • xhr.responseXML
    • xhr.responseText

      • stay xhr.responseType = 'text' , '', When not set ,xhr This property only exists on the instance object , Only then can I call
    • xhr.response

      • stay xhr.responseType = 'text' ,'' when , The value is ( '' )
      • stay xhr.resposneType Other values , The value is ( null )
  • xhr.responseType

    • text
    • document
    • json
    • blob
    • arrayBuffer
    const xhr = new XMLHttpRequest()
    // new  The command always returns an object , Or this object , Or return The object that follows 
    // new  The constructor is called , explain XMLHttpRequest It's a constructor 
    
  • initialization HTTP Request parameters , such as url,http Request method, etc , But not ( Don't send requests )
  • xhr.open() The method is mainly for xhr.send() Methods use

    xhr.open(method, url, async, username, password)

  • Parameters

    • method:http Requested method , Include GET POST HEAD
    • url: Requested address
    • async: Asynchronous or not

      • true, The default value is , Asynchronous requests , Usually you need to call onreadystatechange() Method
      • false, Yes send() Method calls will block , Until the response is fully received

    (2) xhr.send()

  • Send a http request

    xhr.send(body)

  • get request :get The requested parameters can be written directly in open() In the method
  • post request :post The requested parameters are written in send() In the method

    • Be careful :

      • body The data type of the parameter affects requestHeader Medium Content-Type The default value of , How to specify it manually will override the default value
      • If data yes Document type , It's also HTML Document type , be content-type The default value is text/html;charset=UTF-8; Otherwise application/xml;charset=UTF-8;
      • If data yes DOMString type ,content-type The default value is text/plain;charset=UTF-8;
      • If data yes FormData type ,content-type The default value is multipart/form-data; boundary=[xxx]
      • If data It's other types , Will not be set content-type The default value of

    (3) xhr.setRequestHeader()

  • To specify a http The head of the request , Only in readState = 1 Can be called
  • setRequestHeader When you can call

      1. stay readyStaet = 1 when
      1. stay open() After method ,send() Before method
      1. Actually 1 2 It means the same thing

    xhr.setRequestHeader('name', 'value')

  • Parameters

    • name: The name of the head
    • value: The value of the head
  • Be careful

    • setRequestHeader() Methods can be ( Multiple calls ) , It's not worth it ( Cover override ) It is ( Additional append )
    • setRequestHeader() Only in readyState = 1 Can be called , namely open() After method ,send() Before method

    (4) xhr.getResponseHeader()

  • Appoint http Value of response header

    (5) xhr.abort()

  • Cancel current response , Close the connection and end any pending network activity
  • xhr.abort() Will readyState Reset to 0
  • application : Cancel the request , The request took too long , When the response is no longer necessary , Call the method
  • abort: It means termination

    (6) xhr.onreadystatecange()

  • stay readyState Triggered when the state changes
  • xhr.onreadystatechange() stay readyState = 3 when , It is possible to call
  • onreadystatechange Are all lowercase
  • readyState hump

    readyState state

  • UNSENT ------------- xhr Object successfully constructed ,open() Method not called
  • OPEND ------------- open() Method is called ,send() Method not called ,setRequestHeader() Can be called
  • HEADERS_RECEIVED --- send() Method has been called , The response header and response status have been returned
  • LOADING ------------ Response body ( response entity body ) Downloading , In this state, through xhr.response There may already be response data
  • NODE ------------- The whole data transmission process is over , Whether this request succeeds or fails

    (7) xhr.onload

  • Trigger when the request is successful , here readyState = 4
  • Be careful : a key !!!

    • 1. In addition to the xhr.onreadystatechange Of the specified callback function readyState = 4 Time value
    • 2. You can also do it in xhr.onload Value in the event
      xhr.onload = function() {

      //  The request is successful 
      if (xhr.status === 200 ) {
        // do successCallback
      }

      }

    • 3. Judge xhr.status === 200 It's pit. , Because the status code returned when successful is not only 200, The following is more reliable
      xhr.onload = function () {

      // If the request succeeds 
      if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
        // 304 not modified  The resource was not modified   Negotiate the cache 
        // 2 Status code at the beginning , Indicates that the request was successful 
        //do successCallback
      }

      }

    (8) xhr.timeout

  • Set expiration time
  • problem 1: How to determine the start time of the request ? yes ( xhr.onloadstart ) When the event is triggered , That is to say xhr.send() When called
  • analysis : because xhr.open() Just created a link , When there is no real data transmission , Only a call xhr.send() The transmission really starts when
  • problem 2: When is the request over ?
  • analysis :( xhr.loadend ) End when the event is triggered

    (9) xhr.onprogress Download progress information
    (10) xhr.upload.onprogress Upload progress information
    xhr.upload.onprogress = function(e) {
    if ( e.lengthComputable ) {

    const present = e.loaded / e.total * 100;

    }
    }

  • XMLHttpRequest Request case

    XMLHttpRequest Request case 
    
    ----
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    </head>
    <body>
    <button id="buttonId"> Click on , Request data </button>
    <script>
      const button = document.getElementById('buttonId')
      button.addEventListener('click', handleClick, false)
    
      function handleClick() {
        const xhr = new XMLHttpRequest()
        xhr.open('GET', 'http://image.baidu.com/channel/listjson?pn=0&rn=30&tag1= star &tag2= All &ie=utf8', true) // open() Method 
        xhr.setRequestHeader('Content-Type', 'application/json') // setRequestHeader Must be in open() After the method ,send() Call before method , namely  readyState === 1 when 
        xhr.responseType = 'text'
        xhr.timeout = 10000
        xhr.onreadystatechange = function () {
          if (xhr.readyState === 4 && xhr.status === 200) {
            //  Through here  this  Instead of  xhr  It's the same thing 
            //  because  this  Determine the point at run time ,xhr Instance is calling onreadystatechange Method , therefore this Point to xhr example 
            console.log(JSON.parse(this.responseText)) //  Equivalent to  console.log(JSON.parse(xhr.responseText))
          }
        }
        xhr.onload = function () {
          if ((xhr.status >= 200 && xhr.status < 300) || (xhr.status === 304)) {
            console.log(JSON.parse(xhr.responseText), 'xhr.onload It is a callback triggered when the request is completed ')
          }
        }
        xhr.send() //  Send a request 
      }
    </script>
    </body>
    </html>

axios

  1. package.json => main: index.js => The description entry file is index.js
  2. index.js => module.exports = require('./lib/axios');

(1) axios Request process sorting

  • createInstance Function signature :(config) => axios instance
  • var axios = createInstance(defaults), Get into createInstance Internal function
  • <font color=red size="5">var context = new Axios(defaultConfig)</font>
  • <font color=red>Axios</font>

    • function Axios(instanceConfig){...} It's a constructor
    • example

      • defaults

        • this.defaults = instanceConfig
      • interceptors object

        • request object

          • new InterceptorManager() Generated instance object
        • response object

          • new InterceptorManager() Generated instance object
    • Axios.prototype

      • request
      • getUri
      • 'delete', 'get', 'head', 'options', 'post', 'put', 'patch' Wait for the method of request
  • <font color=red>InterceptorManager</font>

    • InterceptorManager It's a constructor

      • InterceptorManager Constructors The generated instance has ( An attribute )

        • handlers

          • Is an array
          • The members of the array are such objects {fulfilled: fulfilled, rejected: rejected} perhaps null
      • InterceptorManager.prototype There are ( Three methods )

        • use
        • eject
        • forEach
  • <font color=red>InterceptorManager.prototype.use - Add interceptor </font>

    • Function signature :(fulfilled, rejected) => (this.handlers.length - 1)
    • Parameters

      • fulfilled
      • rejected
    • Return value

      • (this.handlers.length - 1)
      • Indicates that the object is in this.handers Subscript in array , It is mainly used for InterceptorManager.prototype.eject Method
    • The main role :

        1. towards handlers in push {fulfilled: fulfilled, rejected: rejected} object
        1. Return to one (this.handlers.length - 1) As a way to delete the object ID, In fact, it is the subscript of the member in the array
  • <font color=red>InterceptorManager.prototype.eject - Delete interceptor </font>

    • Parameters

      • id
      • InterceptorManager.prototype.eject(id)
    • The main role :

      • Delete this id Corresponding in handlers The object at that position in the array
      • Be careful : This is not the real deletion , I'm going to take this id The corresponding property is set to null, stay forEach During traversal, it will judge and filter out null term
  • <font color=red>InterceptorManager.prototype.forEach - To filter out null member , Traverse the execution fn(h) </font>

    • Parameters

      • fn
      • InterceptorManager.prototype.forEach(fn)
    • The main role :

      • Traverse this.handlers Array , The value in the array is not equal to null Each object of the as fn(h) And execute
    • Realization :

      • Mainly through utils.forEach To achieve
  • <font color=red>forEach - utils/forEach</font>

    • utils.js Medium forEach Method
    • forEach(obj, fn)
    • The main role

      • If parameters obj yes null and undefined Go straight back to , Not going down
      • If parameters obj yes number,string,boolean,function Then turn it into an array and make the following judgment
      • If parameters obj It's an array ( namely number,string,boolean,function.array Will traverse the array ), Just loop through the array

        • fn.call(null, obj[i], i, obj) i It's an array subscript
      • If parameters obj It's the object

        • fn.call(null, obj[key], key, obj); key It's object's key
  • <font color=blue>mergeConfig</font>

    • Function signature :(config1, config2) => config
    • Parameters :

      • config1
      • config2
    • return

      • config
      • That is, the total after the merger config object
  • <font color=blue>isObject - utils/isObject</font>

    • val !== null && typeof val === 'object'
    • If not null also typeof Is an object true
  • <font color=blue>isArray - utils/isArray</font>

    • Object.prototype.toString.call(val) === '[object Array]'
  • <font color=blue>merge - utils/merge</font>

    • Function signature :(obj1, obj2, ...) => obj
    • Parameters : Object or array , It's better to be a pure object
    • Return value : A merged object
    • principle

        1. Loop through each property of each parameter object
        1. If result The result object is this key Corresponding value It's an object or an array , And the parameter object key Corresponding value It's also an object or array , Just recursively execute merge, Merge the two objects again
        1. If result The result object is this key Corresponding value Not an object or array , Just take the... Of the parameter object directly key by key,value by value Assign a value to result object

          • So the next object has the same properties , be result The property of the object is reassigned to the value exclusive to the following parameters , It will be reassigned, which is equivalent to overwriting
  • <font color=blue>deepMerge - utils/deepMerge</font>

    • and merge The difference between

      • When the parameter object 2 One of the properties in is the object , And the parameter object 1 When there is no such attribute in , Still call recursively deepMerge, Instead of assigning directly
      • The result is :

        • deepMerge Returned object , When this property of the parameter object is modified , No effect deepMerge Returned object
        • merge Returned object , When this property of the parameter object is modified ,merge The property of the returned object will also change
        • namely The difference between a shallow copy and a deep copy
  • <font color=blue>transformData</font>

    • Function signature :(data, headers, fns) =>
  • <font color=blue>getDefaultAdapter</font>

    • Return value :adapter
    • The main role

      • Make different requests according to different environments
      • browser :XMLHttpRequest request
      • node:http https modular
    • Distinguish between browsers and node Environmental Science

      • Browser environment

        • XMLHttpRequest There is
        • There is , load adapter = require('./adapters/xhr')
      • node Environmental Science

        • process There is
        • There is , load adapter = require('./adapters/http')
  • <font color=blue size=5>Axios.prototype.get - With get Method examples </font>

    • Function signature :(url, data) => this.request(utils.merge(config||{}, {method: method, url: url}))
    • this.request It is on the object where the call is made request => Axios On an instance of request => this.request === Axios.prototype.request
  • <font color=blue size=5>Axios.prototype.request</font>

    • Axios.prototype.request(config)
    • (1) If config Is a string , that config = arguments[1] || {};config.url = arguments[0]; otherwise config = config || {};

      • character string

        • config = arguments[1] || {};
        • config.url = arguments[0]
        • axios('example/url'[, config]) It's satisfying config It's a string, be config That's the second parameter , The first parameter is url
      • object

        • config = config || {}
    • (2) Merge config

      • config = mergeConfig(this.defaults, config);
    • (3) Set up config.method

      • If config.method There is , Just turn it into lowercase
      • If config.method non-existent , however his.defaults.method There is ,config.method = this.defaults.method.toLowerCase()
      • Neither of the above exists , Default config.method = get
    • (4) var chain = [dispatchRequest, undefined];

      • Note that there is no implementation dispatchRequest function
    • (5) <font color=blue>dispatchRequest</font>

      • Function signature :(config) => adapter(config).then(value => value, reason => Promise.reject(reason))
      • Return value : After the request is completed , A new promise
    • (6) according to 45:var chain = [(config) => adapter(config).then(value => value, reason => Promise.reject(reason)), undefined]
    • (7) The interceptor skips
    • (8) <font color=blue>var promise = Promise.resolve(config)</font>

      • take config Conversion of objects promise object , The object is resolve state , Its value will be used as then(value => {}) The parameter of the first successful callback of the method is value Value
    • (9) this.interceptors.request.forEach(interceptor => { chain.unshift(interceptor.fulfilled, interceptor.rejected) })

      • Loop traversal request Medium this.handlers Array , Treat each item as interceptor Parameters ,unshift To chain in
      • <font color=blue>chain = [ A successful way to request interceptors , Failure method of request interceptor ,dispatchRequest, undefined]</font>
      • Special attention should be paid here :

        • request: new InterceptorManager()
        • response: new InterceptorManager()
        • <font color=blue>this.handlers In the constructor , Not in the constructor prototype On , namely handles Array on each instance , Are independent of each other </font>

          • <font color=blue>axiosInstance.interceptors.request.use and axiosInstance.interceptors.response.use</font>
          • <font color=blue> Two use It is independent to different handlers in push and unshift object </font>
          • <font color=blue>request yes unsfift in front </font>
          • <font color=blue>response yes push rearwards </font>
    • (10) this.interceptors.response.forEach(interceptor => {chain.push(interceptor.fulfilled, interceptor.rejected)})

      • and 9 Empathy
      • Loop traversal response Medium handlers Array , Put each item here as forEach The parameters of the callback function
      • <font color=blue>chain = [ A successful way to request interceptors , Failure method of request interceptor ,dispatchRequest, undefined, A successful way to respond to interceptors , The failure method of response interceptor ]</font>
    • (11) while loop chain Array , perform <font color=blue>promise = promise.then(chain.shift(), chain.shift())</font>

      • promise Is the merged final configuration object of the incoming request
      • Each time from chain Take two elements from the front to the back of the array
      • <font color=blue>var chain = [ A successful way to request interceptors , Failure method of request interceptor , (config) => adapter(config).then(value => value, reason => Promise.reject(reason)), undefined, A successful way to respond to interceptors , The failure method of response interceptor ]</font>
      • Be careful : there config Namely (8) In the step config Converted into promise object , The object will act as .then The parameter that the method successfully calls back is config
      • obtain :
    
    var chain = [ A successful way to request interceptors , Failure method of request interceptor , (config) => adapter(config).then(value => value, reason => Promise.reject(reason)), undefined,  A successful way to respond to interceptors , The failure method of response interceptor ]
    
    promise = Promise.resolve(config);
     .then(' Request successfully intercepted 2', ' Request failed to intercept 2') //  Pass down config ,  Be careful 2 stay 1 front ,unshift
     .then(' Request successfully intercepted 1', ' Request failed to intercept 1')
     .then(dispatchRequest, undefined) //  Actually send the request ,(config) => adapter(config).then(value => value, reason => Promise.reject(reason))
     .then(' Response successfully intercepted 1', ' Response failed to intercept 1')
     .then(' Response successfully intercepted 2', ' Response failed to intercept 2') //  Be careful 2 stay 1 Back ,push
    
     - (12)  Finally back to  promise 
         - then() Back to a new promise example 
         -  You can go through  .then()  Method to get the result value of the request  

(2) axios Request flow , Interception principle - Source code

1. package.json => main => index.js => equire('./lib/axios')

1. package.json => main => index.js => equire('./lib/axios')

'use strict';

var utils = require('./utils');·
var bind = require('./helpers/bind');
var Axios = require('./core/Axios');
var mergeConfig = require('./core/mergeConfig');
var defaults = require('./defaults');

function createInstance(defaultConfig) {
  // createInstance(defaultConfig)
  //  Parameters : Configuration object 
  //  effect : Create a axios example , And back to 

  var context = new Axios(defaultConfig);
  //  Generate axios example context
  //  Instance attributes 
    //  Instance attributes :defaults = instanceConfig =  The parameter object passed in defaultConfig
    //  Instance attributes : interceptors  object 
    // interceptors.request = new InterceptorManager()
    // interceptors.response = new InterceptorManager()
      //  Instance attributes :handlers  An array 
      //  Properties on prototype objects :use eject forEach
        // use    =>  towards  handlers  add to  {fulfilled: fulfilled, rejected: rejected} object , Returns an array index , Subscripts are used for eject
        // eject  =>  towards  handlers Set the subscript member to null, It is equivalent to deleting , Because in forEach Will judge whether it is null
        // forEach =>  loop handlers Array , Proceed accordingly  fn(h); 
          // fn  =>  yes forEach Passed in parameter function 
          // h   =>  yes handlers Each member of , object 4
  //  Properties on prototype objects  
    // request 
    // getUri
    // 'delete', 'get', 'head', 'options', 'post', 'put', 'patch'  Wait for the method of request 
  //  summary :
    // (1) context There are  defaults interceptors request getUri 'delete', 'get', 'head', 'options', 'post', 'put', 'patch'  Wait for the method of request 
    // (2) interceptors.request  and   interceptors.response  There are  handlers use eject forEach

  var instance = bind(Axios.prototype.request, context);
  // bind  The method is similar to that of the original sound bind
  //  here bind Is to return a function  warp() => Axios.prototype.request.apply(context, [...arguments])
  //  therefore  instance  It's a function , This function will request Medium this Binding in context And return the execution result 
  // var instance = warp() => Axios.prototype.request.apply(context, [...arguments])


  utils.extend(instance, Axios.prototype, context);
  //  Inherit the prototype 
  // utils.extend effect :
  //  take  Axios.prototype  All properties and methods are assigned to  instance
  //  If it is  Axios.prototype  The method on the , Try to make this Bound to the context
  //  Final : instance The method has  Axios.prototype  All properties and methods on 


  utils.extend(instance, context);
  //  Inheritance instance 
  //  take  context  All properties and methods on are assigned to   instance

  return instance;
}


var axios = createInstance(defaults);
//  establish axios example 


axios.Axios = Axios;
// Expose Axios class to allow class inheritance
//  Can pass  new axios.Axios()


axios.create = function create(instanceConfig) {
  return createInstance(mergeConfig(axios.defaults, instanceConfig));
};
// Factory for creating new instances
//  summary : establish axios Three methods of example 
// 1. axios(configObject)
  // axios  Itself is such a function  warp() => Axios.prototype.request.apply(context, [...arguments])
// 2. axios.create(configObject)
  //  call createInstance(mergeConfig(axios.defaults, instanceConfig))
// 3. new axios.Axios().request(configObject)



axios.Cancel = require('./cancel/Cancel');
// Cancel(message)  It's a constructor 
//  example 
  // message
//  Prototype 
  // toString
  // _CANCEL = true
axios.CancelToken = require('./cancel/CancelToken');
// CancelToken(executor)  It's a constructor 
  //  example 
    // promise
    // reason
  //  Prototype 
    // throwIfRequested
  //  Static methods 
    // source
      //  return  {token: token, cancel: cancel}  Such an object 
// new CancelToken(executor)
  //  This is called in development : cancelToken = new axios.CancelToken(function executor(c) { cancel = c}) !!!!!!!!!!!!!!!!!!!!!!!!!!
  // 1.  If  executor  It's not a function , Throw the wrong 
  // 2. this.promise =  One promise object , Always out of pending state , Calling resolve(message) Change state when 
  // 3. executor The argument to a function is also a function , namely  c  function 
  // 4. c  The main function is  resolve(new Cancel(message))  When executed ,
  // 5.  stay Axios.prototype.request => dispatchRequest => defaults => getDefaultAdapter
    // throwIfCancellationRequested(config)
      //  If config.cancelToken There is , config.cancelToken.throwIfRequested()  namely  throw this.reason  namely  throw new Cancel(message)  That is, a  {message: 'xxxx'}
  // 5.  stay Axios.prototype.request => dispatchRequest => defaults => getDefaultAdapter => xhr.js  It's all right XMLHttpRequest request 
    //  Will judge  config.cancelToken  Whether there is 
    //   There is , use  abort()  Interrupt execution , take resolve(message) Of message As then() Parameters of the callback reject(message)
  // 6.  summary :
    // config.cancelToken = {
    //   promise: new Promise(function(resolve){
    //     resolve({ message: '...'})
    //   }),
    //   reason: { message: '....' }
    // }

axios.isCancel = require('./cancel/isCancel');
//  Sign a , Used to mark whether to cancel 
//  The above three attributes are mainly used to cancel the request 


// Expose all/spread
axios.all = function all(promises) {
  return Promise.all(promises);
};
axios.spread = require('./helpers/spread');

module.exports = axios;


module.exports.default = axios;
// Allow use of default import syntax in TypeScript
//  That is, it can be done through  import axios from 'axios' Mode introduction 

2. lib/core/Axios.js ---------- Axios There are various request methods in and Axios.prototype.request Method

3. With axios.get('www.baidu.com', {....}) get Request as an example

utils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {
  /*eslint func-names:0*/
  Axios.prototype[method] = function(url, config) {
    return this.request(utils.merge(config || {}, {
      method: method,
      url: url
    }));
  };
});
//  The code above represents : Traversal array , Add various methods 
//  such as :Axios.prototype.get = function(url, config) { return request(....) }
//  Be careful :this.request() It can only be determined when calling this The direction of , Let's go through  axios.get() In this case  this  Namely  axios example 



-----
 analysis : First look at  utils.forEach  This function defines 
1.  Parameters :obj  and  fn
2.  If obj yes null perhaps undefined Directly return to interrupt execution 
3.  If it is  number,string,boolean,function,symbol Just put  obj  Construct into an array 
4.  If  obj  It's an array , That is, through 3 The processed data types are arrays  =================> fn.call(null, obj[i], i, obj) 
    // obj[i] Is the value of the array 
    // i  It's a subscript 
    // obj  It's the original array 
5.  If  obj  It's the object ,=================================================> fn.call(null, obj[key], key, obj)
    // obj[key] Is the value corresponding to the attribute of the object 
    // key  Is a property of an object 
    // obj  It's the original object 
function forEach(obj, fn) {
  if (obj === null || typeof obj === 'undefined') {
    return;
  }
  if (typeof obj !== 'object') {
    /*eslint no-param-reassign:0*/
    obj = [obj];
  }
  if (isArray(obj)) {
    for (var i = 0, l = obj.length; i < l; i++) {
      fn.call(null, obj[i], i, obj);
    }
  } else {
    for (var key in obj) {
      if (Object.prototype.hasOwnProperty.call(obj, key)) {
        fn.call(null, obj[key], key, obj);
      }
    }
  }
}

4. Axios.prototype.request - The core method of the request , Each method calls the method

Axios.prototype.request = function request(config) {
  // axios('example/url'[, config])  This situation config It's just one. string
  // axios  Namely  warp() => Axios.prototype.request.apply(context, [...arguments])  Such a function 
  if (typeof config === 'string') {
    config = arguments[1] || {}; //  The second parameter is config object 
    config.url = arguments[0]; //  The first parameter is url
  } else {
    config = config || {};
  }

  config = mergeConfig(this.defaults, config); 
  //  Merge the passed in parameter object and the default parameter object according to different conditions , Return to the merged config
  //  Not yet mergeConfig Specific consolidation rules 


  if (config.method) {
    config.method = config.method.toLowerCase();
  } else if (this.defaults.method) {
    config.method = this.defaults.method.toLowerCase();
  } else {
    config.method = 'get';
  }
  //  If the incoming config There is method, Use the incoming method And turn to lowercase 
  //  If it doesn't exist , But by default cofig in method There is , Use the default 
  //  It doesn't exist ,get Method 
  


  var chain = [dispatchRequest, undefined];
  // dispatchRequest ---------------------------------------------------------------------------------------  analysis 1
  // var chain = [(config) => adapter(config).then(), null]
  
  
  
  var promise = Promise.resolve(config);
  //  The passed in parameter object  config  Turn into  promise  object 

  this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
    chain.unshift(interceptor.fulfilled, interceptor.rejected);
    //  towards chain Array loop unshift
    // chain = [ A successful way to request interceptors 2, Failure method of request interceptor 2,  A successful way to request interceptors 1, Failure method of request interceptor 1, (config) => adapter(config).then(), null]
  });
  // this.interceptors.request.forEach ---------------------------------------------------------------------  analysis 2

  this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
    chain.push(interceptor.fulfilled, interceptor.rejected);
     //  towards chain Array loop push
    // chain = [ A successful way to request interceptors 2, Failure method of request interceptor 2,  A successful way to request interceptors 1, Failure method of request interceptor 1, (config) => adapter(config).then(), null,  A successful way to respond to interceptors 1, The failure method of response interceptor 1,  A successful way to respond to interceptors 2, The failure method of response interceptor 2]
  });

  while (chain.length) {
    promise = promise.then(chain.shift(), chain.shift());
    //  Take out two methods at a time from left to right 
    // promise = Promise.resolve(config);
      // .then(' Request successfully intercepted 2', ' Request failed to intercept 2') //  Pass down config ,  Be careful 2 stay 1 front ,unshift
      // .then(' Request successfully intercepted 1', ' Request failed to intercept 1')
      // .then(dispatchRequest, undefined) //  Actually send the request ,(config) => adapter(config).then(value => value, reason => Promise.reject(reason))
      // .then(' Response successfully intercepted 1', ' Response failed to intercept 1')
      // .then(' Response successfully intercepted 2', ' Response failed to intercept 2') //  Be careful 2 stay 1 Back ,push
  }

  return promise;
  //  Finally back to  promise 
  // then() Back to a new promise example 
  //  You can go through  .then()  Method to get the result value of the request  
};
 analysis 1 
dispatchRequest
 Function signature :(config) => adapter(config).then()


function throwIfCancellationRequested(config) {
  if (config.cancelToken) {
    config.cancelToken.throwIfRequested();
  }
}

module.exports = function dispatchRequest(config) {
  throwIfCancellationRequested(config);
  //  If config in cancelToken There is , It means cancel the request ,throw this.reason = throw new Cancel(message) = throw {messsage: '...'}

  config.headers = config.headers || {};

  config.data = transformData(
    config.data,
    config.headers,
    config.transformRequest
  );

  config.headers = utils.merge( 
    config.headers.common || {},
    config.headers[config.method] || {},
    config.headers
  );
  // tuils.merge(obj1, obj2)
    //  Loop through all parameter objects , And traverse each attribute of each parameter object 
    //  Assign each attribute and value to the new object 
    //  If the property of the new object and the property of the parameter object are both one object , recursive 
    //  If the new object does not exist or is not an object , Direct assignment 
    
    //  Pay attention to distinguish between utils.deepMerge  and  utils.merge
    // deepMerge =>  When the property does not exist in the new object , Parameter object when the property is an object , No direct assignment , It's a shallow copy 

  utils.forEach(
    ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],
    function cleanHeaderConfig(method) {
      delete config.headers[method];
    }
  );

  var adapter = config.adapter || defaults.adapter;
  // adapter According to the browser environment or node The environment uses different requests 
  //  browser  => XMLHttpRequest To judge  => XHR
  // node => process To judge  => http https

  return adapter(config).then(function onAdapterResolution(response) {
    //  Return the requested data ,promise packing 
    
    throwIfCancellationRequested(config);
    //  If config.cancelToken There is , Terminate response , Throw an error 

    // Transform response data
    response.data = transformData(
      response.data,
      response.headers,
      config.transformResponse
    );

    return response; //  Return the request result and wrap the processed object 
  }, function onAdapterRejection(reason) {
    if (!isCancel(reason)) {
      throwIfCancellationRequested(config);

      // Transform response data
      if (reason && reason.response) {
        reason.response.data = transformData(
          reason.response.data,
          reason.response.headers,
          config.transformResponse
        );
      }
    }

    return Promise.reject(reason);
  });
};
 analysis 2
InterceptorManager.prototype.forEach 
 Parameters :fn
 effect : loop handlers Array , Take each member as an argument to the destroy function , The perform  fn(h)
 Be careful :
1. this.handlers yes  [{fulfilled: fulfilled,rejected: rejected}]  Such an array   Or the members are  null
2. axios.interceptors.requet.handlers  and  axios.interceptors.requet.handlers  It's a different array , Because it was executed twice  new InterceptorManager()  It's a different example 
    - request: new InterceptorManager()
    - response: new InterceptorManager


InterceptorManager.prototype.forEach = function forEach(fn) {
  utils.forEach(this.handlers, function forEachHandler(h) {
    if (h !== null) {
      fn(h);
    }
  });
};

(3) axios Cancel the request - Source code

  • Take the use of this cancellation request as an example

    const CancelToken = axios.CancelToken;
    const source = CancelToken.source(); // ----------------------------- source Factory function 
    
    axios.get('/user/12345', {
    cancelToken: source.token // --------------------------------------- token
    }).catch(function (thrown) {
    if (axios.isCancel(thrown)) {
      console.log('Request canceled', thrown.message);
    } else {
      // handle error
    }
    });
    
    //  Cancel the request 
    source.cancel('Operation canceled by the user.'); // ----------------- cancel function 

1. lib/axios.js

axios.Cancel = require('./cancel/Cancel');
axios.CancelToken = require('./cancel/CancelToken');
axios.isCancel = require('./cancel/isCancel'); 

2. axios.CancelToken = require('./cancel/CancelToken')

  • CancelToken(executor)
  • CancelToken It's a constructor

    • example

      • promise
      • reason
  • Be careful :<font color=blue> Generated cancelToken The instance is to be mounted to the request method config Object </font>

    • like this axios.get('/user/12345', { cancelToken: source.token }).catch()
    'use strict';
    
    var Cancel = require('./Cancel');
    
    
    function CancelToken(executor) {
    if (typeof executor !== 'function') {
      // executor It has to be a function 
      throw new TypeError('executor must be a function.');
    }
    
    var resolvePromise;
    this.promise = new Promise(function promiseExecutor(resolve) {
      resolvePromise = resolve;
      // this.promise  It's a place where pending State of promise object 
    });
    
    var token = this; //  Fix this
    
    executor(function cancel(message) {
    //  Here is the call  executor, When calling, another cancel Function as  executor Parameters of 
    // executor  It's incoming  CancelToken  Parameter function 
    
    // executor Of  (  Parameters  )  Also a  (  function  ), namely  cancel  function 
    //  Here is  cancel  Function definition 
    // cancel The argument to the function is  message
    
      if (token.reason) {
        return;
      }
    
      token.reason = new Cancel(message);
      // this.resaon non-existent , Just  new Cancel(message)
      // new Cancel(message)  It's a constructor 
        //  example 
          // messge
        //  Prototype 
          // toString
          // __CANCEL__ = true
      //  therefore 
        // reason  It's just one.  {message: 'xxxx'}  The object of 
    
      resolvePromise(token.reason);
      //  change  this.promise  The state of ,  from pending  Turn into  resolve
    });
    }
    // CancelToken  summary 
    // CancelToken The instance properties generated by the constructor have two  promise  and  reason
    // token = {
    //   promise: new Promise(resolve => resolve({message: 'xxxxxxx'})),
    //   reason: {messge: 'xxxxxx'}
    // }
    
    //   Be careful : Generated cancelToken The instance is to be mounted to the requested config Object  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      // `axios.get('/user/12345', { cancelToken: source.token }).catch()` like this  !!!!!!!!!!!!!!!!!!!!!!!!!!!!
    
    
    CancelToken.prototype.throwIfRequested = function throwIfRequested() {
    // reason There is , Just throw it wrong 
    if (this.reason) {
      throw this.reason;
    }
    };
    
    
    CancelToken.source = function source() {
    //  Static methods  source
    var cancel;
    var token = new CancelToken(function executor(c) {
      //  there c Is the above  executor The parameters of the function  cancel function 
      // c The main function is : hold this.promise The status of the pending Turn into resolve
      cancel = c;
    });
    return {
      token: token, // token yes {promise: new Promise(resolve => resolve({messge: ''})), reason: {message: ''}} Such an object 
      cancel: cancel //  Cancel function 
    };
    };
    
    module.exports = CancelToken;
    

(3) When cancel() Function execution time , Request the incoming config Object cancelToken Property object promise The status changes to resolve after , Just enter dispatchRequest

  • <font color=blue> Judgment is needed at all stages config in cancelToken Whether there is , There is a mistake , Interrupt execution </font>
  • Before request
  • When asked
  • Wait after response
module.exports = function dispatchRequest(config) {
  throwIfCancellationRequested(config);
  //  Before sending , Will judge config Whether there is cancelToken
  //  If it exists, throw it wrong , Interrupt execution 

  config.headers = config.headers || {};

  // Transform request data
  config.data = transformData(
    config.data,
    config.headers,
    config.transformRequest
  );

  // Flatten headers
  config.headers = utils.merge(
    config.headers.common || {},
    config.headers[config.method] || {},
    config.headers
  );

  utils.forEach(
    ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],
    function cleanHeaderConfig(method) {
      delete config.headers[method];
    }
  );

  var adapter = config.adapter || defaults.adapter;

  return adapter(config).then(function onAdapterResolution(response) {
    //  stay  adapter(config)  in  => default.js in  => adapter In folder  =>  Browser environment  xhr.js  in 
    //  Made the following judgment 
        // if (config.cancelToken) {
        //   config.cancelToken.promise.then(function onCanceled(cancel) {
        //     if (!request) {
        //       return;
        //     }
        //     request.abort();
        //     reject(cancel);
        //     request = null;
        //   });
        // }
        //  Be careful : above config.cancelToken.promise.then() Of promise The change of state is when  cancel  Function time , become fulfilled state 
        //  in other words : When cancel Function execution time , Only if you ask  abort  Interrupt request , And throw it wrong 
    
    throwIfCancellationRequested(config);
    //  Please complete , When the corresponding data is obtained , Also judge config Whether there is cancelToken
    //  If it exists, throw it wrong , Interrupt execution 


    // Transform response data
    response.data = transformData(
      response.data,
      response.headers,
      config.transformResponse
    );

    return response;
  }, function onAdapterRejection(reason) {
    if (!isCancel(reason)) {
      throwIfCancellationRequested(config);
      //  Judge when something goes wrong config Whether there is cancelToken
    //  If it exists, throw it wrong , Interrupt execution 


      // Transform response data
      if (reason && reason.response) {
        reason.response.data = transformData(
          reason.response.data,
          reason.response.headers,
          config.transformResponse
        );
      }
    }

    return Promise.reject(reason);
  });
};

(4) stay dispatchRequest => adapter => xhr in

if (config.cancelToken) {
  //  If cancelToken There is 
  config.cancelToken.promise.then(function onCanceled(cancel) {
    //  When cancel() Function execution time  => config.cancelToken.promise The state is already resolve({message: message})
    //  The perform  cancel  Function time , the  resolve  operation 
    if (!request) {
      return;
    }
    request.abort(); //  Interrupt request 
    reject(cancel); //  Throw an error ,message
    // Clean up request
    request = null;
  });
}

Use of examples :axios Cancel request in CancelToken stay vue Application in the project

  • demand 1

    • If there is only one request per page , So you can go through mixin hold token and cancel Injected into each component data in
  • demand 2

    • Every route jump , Cancel all requests of the last route
      1. When the route jumps , Use routing guard beforeEach, perform store All in cancel Cancel function
      1. stay axios Your request is being intercepted

        • new axios.CancelToken(c => cancel = c) Assign an instance to config.cancelToken attribute ;
        • take cancel function push To store Storage in

Project source code - Source analysis address

Information

Chuan Shen https://juejin.im/post/684490...
a key cancelToken https://juejin.im/post/684490...
https://juejin.im/post/684490...
axios Official website https://github.com/axios/axios
vue and react How to use axios Cancel the request https://juejin.im/post/684490...

copyright notice
author[woow_ wu7],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2021/08/20210825093437064M.html

Random recommended