current position:Home>How does Axios cancel requests that occur

How does Axios cancel requests that occur

2021-08-23 05:00:39 Rockergmail

Interface Analysis

https://github.com/axios/axio...

 Usage 1 
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.post('/user/12345', {
  name: 'new name'
}, {
  cancelToken: source.token
}).catch(function (thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
    // handle error
  }
});
source.cancel('Operation canceled by the user.');
 Mode 2 
const CancelToken = axios.CancelToken;
let cancel;
axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    cancel = c;
  })
});
cancel();

Is to add cancelToken Parameters , The value can be an object , There are operations that can be cancelled .

Source code analysis

  1. Refer to the use case , location axios.CancelToken, To find the source code
    1629275628(1).png
    https://github.com/axios/axio...

    isCancel.js  Determine whether cancel object 
    module.exports = function isCancel(value) {
      return !!(value && value.__CANCEL__);
    };
    Cancel.js  structure cancel object , Used to identify cancel Of message Information 
    function Cancel(message) {
      this.message = message;
    }
    Cancel.prototype.toString = function toString() {
      return 'Cancel' + (this.message ? ': ' + this.message : '');
    };
    Cancel.prototype.__CANCEL__ = true;
    module.exports = Cancel;
    CancelToken.js
    var Cancel = require('./Cancel');
    function CancelToken(executor) {
      //  The actuator must be a function 
      if (typeof executor !== 'function') {
     throw new TypeError('executor must be a function.');
      }
      var resolvePromise;
      //  Create a promise, And record resolve Method , For use in actuators 
      this.promise = new Promise(function promiseExecutor(resolve) {
     resolvePromise = resolve;
      });
      var token = this;
      // cancel The core method of : use reason To record the cancellation reason , And used to determine whether it has been cancelled . and resolve Drop the top promise
      executor(function cancel(message) {
     if (token.reason) {
       // Cancellation has already been requested
       return;
     }
    
     token.reason = new Cancel(message);
     resolvePromise(token.reason);
      });
    }
    //  Judge whether it has been cancelled , If it's cancelled , The reason for cancellation is thrown 
    CancelToken.prototype.throwIfRequested = function throwIfRequested() {
      if (this.reason) {
     throw this.reason; 
      }
    };
    //  Static methods , Return an instance 
    //  The essence of mode 2 is the following implementation 
    CancelToken.source = function source() {
      var cancel;
      var token = new CancelToken(function executor(c) {
     cancel = c;
      });
      return {
     token: token,
     cancel: cancel
      };
    };
    module.exports = CancelToken;
  2. Search code cancelToken, location ib/core/dispatchRequest.js
    1629273989(1).png

    function throwIfCancellationRequested(config) {
      if (config.cancelToken) {
     config.cancelToken.throwIfRequested();
      }
    }
  3. trace throwIfCancellationRequested Where to call , Click on the function throwIfCancellationRequested, Press F12, See where the call is
    1629274505.png
    1629274505(1).png
    1629274505(2).png
    in other words , At initialization time 、 When the request succeeds and when the request fails , Determine whether the request has been initiated , If initiated , The reason for cancellation is thrown .
    Solved the problem of user calling cancel The timing of , Before the request is initiated, the request is intercepted , After the request is made , Whatever the outcome , Will no longer enter the processing logic .
  4. Follow up , By promisify Of xhr/http
    1629274912(1).png
    Code shows , Before making a request , Judge whether it's passed cancelToken. If you pass in , Then add cancelToken Of promise Callback , Cancel the request . Pay attention to CancelToken.js, hold cancel The method is exposed , The user calls cancel After the method, you will promise resolve fall .

Recombing

  1. xhr/http, Before making a request , Determine if there is an incoming cancelToken, Also on promise Incoming callback , The origination of the intercept request . therefore CancelToken.js There needs to be one promise inform xhr/http Whether the user has executed cancel 了 .
  2. dispatchRequest.js, Initializing 、 The request is successful 、 When the request fails , Judge whether it has been cancel 了 , If so, throw an error . So we need to CancelToken.js A variable to determine whether it has been cancel too , And one. throwIfRequested Method to judge .
  3. call cancel The moment of , Users may want to do some custom operations . Therefore, the actuator can be passed in by the user , Or provide a static method to create a new instance , And the actuator has been written .

What is worth learning

  1. promise We often call it according to the standard method , stay promise Perform... In vivo resolve,reject

    new Promsie((resolve, reject) => {
      ...
      if (...) {
         resolve('xxx')
       } else {
         reject('yyy')
       }
    })

    In fact, you can be flexible , Use variables to save resolve/reject, Perform... Outside , Increase flexibility .

    let resolver;
    new Promsie((resolve, reject) => {
      ...
      resolver = resolve;
    })
    ...
    resolver('xxx')
    ...
  2. The argument to a function is a function , You need to understand why it can be called by the user , Direct use t To express CancelToken.js The actuator that has been written

    function CancelToken(executor) {
      ...
      // executor Function call 
      executor(function cancel(message) {
         if (token.reason) {
           return;
         }
         token.reason = new Cancel(message);
         resolvePromise(token.reason);
      });
      ...
    }
    CancelToken.source = function source() {
      var cancel;
      // executor Function definition 
      var token = new CancelToken(function executor(c) {
     cancel = c;
      });
      return {
     token: token,
     cancel: cancel
      };
    };

    To simplify the

    var cancel;
    //  Function definition 
    function executor(c) {
     cancel = c;
    }
    //  Function call 
    execotr(() => {console.log('abc'})

    in other words , When defining functions , Save a global variable to the information of local variables , This is to reference the information passed in by the user .
    Because there are variable references , So I think executor It's also a closure .

  3. When designing a sub function , Extend for attributes .

copyright notice
author[Rockergmail],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2021/08/20210823050036421n.html

Random recommended