This is the first day of my participation in the August Challenge. For details, see:August is more challenging

You’re familiar with axios request encapsulation, but it’s more likely to involve calling the create method to create an instance and overwriting the instance’s interceptors. Sometimes, however, you need to add the ability to cancel repeated requests on top of this, which you’ll implement next.

Axios requests simple encapsulation

Start with a simple encapsulation of AXIos, where the business logic associated with the interceptor is not added for the sake of simplicity.

import axios from 'axios';

const instance = axios.create({
  // ...
});

// Request the interceptor
instance.interceptors.request.use(config= > {
    return config;
}, err= > {
    return Promise.reject(err);
});

// Respond to interceptors
instance.interceptors.response.use(res= > {
    return res.data;
}, err= > {
    return Promise.reject(err);
});

export default instance;
Copy the code

Cancel duplicate request

Cancel normal request

The abort() method is used to cancel a normal XMLHttpRequest request.

var ajax = new XMLHttpRequest();
ajax.open('GET'.'/abc');
ajax.send();
setTimeout(() = > {
  ajax.abort(); Cancel the current request
}, 300);
Copy the code

Cancel the AXIOS request example

CancelToken cancelToken cancelToken cancelToken cancelToken cancelToken cancelToken cancelToken cancelToken cancelToken cancelToken

const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get('/user/12345', {
  cancelToken: source.token
}).then(res= > {});

// The arguments in the cancel method are optional
source.cancel('Operation canceled by the user.');
Copy the code

In addition to the above method, axios officially has another way:

const CancelToken = axios.CancelToken;
let cancel;

axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // Where c is the method to cancel the current request, we assign C to the variable cancelcancel = c; })});// Call the cancel method
cancel();
Copy the code

The next way to cancel an AXIos request is to use this, with the ability to cancel the current request as a parameter to the CancelToken constructor.

Implement the unrepeatable request class

Implementation ideas:

Cancel repeated requests. This is mainly for the situation where multiple repeated requests are sent. For example, if two identical requests are sent in the same operation, the previous request will be cancelled while the latter one is really sent.

How can you tell if a request is repeated? Here can request the address of the url, method, request parameters params | data these values to do the only judgment. If this information is identical on both requests, then you can determine that the two requests are duplicate.

If the request is repeated, what should be done next? Cancel by calling the cancel method, of course, but how do you know how to get the cancel method for this request? In fact, this is how to associate the current request with the corresponding cancel, which can be stored by Object or Map. The information of the current request is used as the key, and the corresponding cancel method is used as the value, and stored in the Object or Map. Then you can either cancel based on the current request information or the corresponding cancellation method. The cancel method for each request requires a call to new CancelToken().

Code implementation (cancelRequest.js) :

import qs from 'qs'; // Introduce QS to serialize request parameters
export default class CancelRequest {

    constructor(map) {
        this.cancelReqMap = this.isMap(map) ? map : new Map(a); }// Check whether the data format is map
    isMap(data) {
        if (Object.prototype.toString.call(data) === "[object Map]") return true;
    }

    // Concatenate the request configuration information 'config' to generate a string consisting of 'URL, method, params, data'
    generateCancelReqKey(config) {
        let { url, method, params, data } = config;
        return [url, method, qs.stringify(params), qs.stringify(data)].join('&');
    }
    
    // Add the request information and the corresponding cancellation method to the cancelReqMap attribute
    addCancelReqKey(config, cancelToken) {
        const cancelReqKey = this.generateCancelReqKey(config);
        config.cancelToken = config.cancelToken || new cancelToken((cancel) = > {
            if (!this.cancelReqMap.has(cancelReqKey)) {
                this.cancelReqMap.set(cancelReqKey, cancel); }}); }// Call the cancellation method based on the current request information
    cancelReq(config) {
        const cancelReqKey = this.generateCancelReqKey(config);
        if (this.cancelReqMap.has(cancelReqKey)) {
            const cancel = this.cancelReqMap.get(cancelReqKey);
            cancel(cancelReqKey);
            this.removeRequestKey(config); }}// Delete the cancelReqMap attribute
    removeRequestKey(config) {
        const cancelReqKey = this.generateCancelReqKey(config);
        this.cancelReqMap.delete(cancelReqKey); }}Copy the code
  1. Introducing QS is actually serializing the request parameters,qs.stringify({username: 'admin', password: '123'}) === 'username=admin&password=123';
  2. An object-oriented approach is used to encapsulate the cancellation request. Because the request information and the corresponding cancellation method will be stored for later look-ups, here throughMapThe type ofcancelReqMapProperty to store. Used hereES6In theMapData structures, because their keys are not limited to strings, can be of various data types, which is more sophisticated than ordinary objects.
  3. generateCancelReqKeyThis method is based on the request configuration informationconfigTo generate theUrl, method, params, dataString.
  4. addCancelReqKeyThis method mainly adds the request information and the corresponding cancellation method tocancelReqMapOn the property. The corresponding cancellation method is callednew cancelToken()In order to obtain.
  5. cancelReqThis method mainly calls the corresponding cancellation method according to the current request information, and finally the current request information and cancellation method fromcancelReqMapProperty.
  6. removeRequestKeyDelete according to the requested configuration itemcancelReqMapThe corresponding value of

Perfect axios request encapsulation

import axios from 'axios';
import CancelRequest from './CancelRequest.js';

// Instantiate the cancel request object
let cancelRequest = new CancelRequest();

const instance = axios.create({
  // ...
});

// Request the interceptor
instance.interceptors.request.use(config= > {
  	// Check to see if the same request exists before and cancel if so.
  	cancelRequest.cancelReq(config); 
  	// Record the current request
    cancelRequest.addCancelReqKey(config, axios.CancelToken); 
    return config;
}, err= > {
    return Promise.reject(err);
});

// Respond to interceptors
instance.interceptors.response.use(res= > {
  	// Remove the successful request record
  	cancelRequest.removeRequestKey(res.config);
    return res.data;
}, err= > {
  	// Remove the failed request record
  	cancelRequest.removeRequestKey(err.config || {});
    if (axios.isCancel(err)) {
        console.log('Repeat request information:' + err.message);
    }
    return Promise.reject(err);
});

export default instance;
Copy the code

conclusion

This article mainly introduces the encapsulation of AXIOS requests and the function of canceling repeated requests, here cancel the request, it is possible that the request has not been sent or has reached the server to be canceled, if you are interested in the principle of request interception, you can read the AxiOS source code interpretation (below).

If you see something wrong or could be improved, feel free to comment. If you think it’s good or helpful, please like, comment, retweet and share. Thank you