Hello, I’m JL😄

Growing up together is my pursuit all the time! ✹

Hope the following share can let you gain 💊

background

In daily development, we often use the search box to search:

When we enter the number repeatedly enter, or constantly click the search button next to it, the request will be sent under normal circumstances, or other scenarios such as button click, etc., in the case of weak network or interface card, the same HTTP request will be triggered continuously, that is, the possible problems:

1. Excessive repeated HTTP requests waste performance. 2. The current search result may return the interface requested before, causing data confusion.Copy the code

At the same time, we often need to configure on the existing project, there may be a large cost of change, the following introduces a method of less change, combined with the conventional cancellation of repeated request configuration, with the minimum cost to embed in the existing project.

General solution: Cancel repeated requests

Definition: Automatically cancels the next request for the same interface in the last pending state.

Axios is a powerful Promise-based client that is widely used in corporate projects. Here’s how Axios can configure to cancel repeated requests.

1  ⃣ abort

The UNDERLYING Axios initiates the HTTP request through the XMLHttpRequest object, which provides abort to cancel the request:

Of course, this method is relatively primitive, but let’s look at another method that is currently popular.

2  ⃣ CancelToken

Inside Axios is another method that has been wrapped to cancel the request, throughCancelTokenTo achieve the action to cancel the request:

CancelToken can also be created by passing an executor function to the CancelToken constructor: CancelToken

With the request in mind, let’s take a look at how to configure and seamlessly access existing project generic Axios.

Train of thought

1 auxiliary function generateReqKey

You need a storage method called generateReqKey, which stores the Map object pendingRequest, the unique key value of the request based on the current request information, and the cancel function.

Unique key value can refer to: request method, parameter, address, can be serialized by QS, increase point security ~

function generateReqKey (config) { 
    const { method, url, params, data } = config
    return [method, url, Qs.stringify(params), Qs.stringify(data)].join("&")
}
Copy the code

2 auxiliary function pendingRequest

You need a pendingRequest method to add the current request information to the pendingRequest object, using the Axios CancelToken method

const pendingRequest = new Map() function addPendingRequest (config) { const requestKey = generateReqKey(config) // With the above generateReqKey method config. CancelToken = config. CancelToken | | new axios. CancelToken (= > {if ((cancel)! pendingRequest.has(requestKey)) { pendingRequest.set(requestKey, cancel) } }) }Copy the code

3 auxiliary function removePendingRequest

You need a removePendingRequest method that checks for duplicate requests and, if so, cancels the sent request and clears the storage.

Function removePendingRequest (config) {const requestKey = generateReqKey(config) (pendingRequest.has(requestKey)) { const cancelToken = pendingRequest.get(requestKey) cancelToken(requestKey) pendingRequest.delete(requestKey) } }Copy the code

4  ⃣ configuration

@param {Boolean} reqCancel * @returns {any} */ const HTTP = (userCancel = false) => { Const service = axios.create({withCredentials: true, // Allow cookie timeout across domains: 30000 }) // request interceptor service.interceptors.request.use(config => { ... Do some thing if (reqCancel) {removePendingRequest(config) addPendingRequest(config)} return config}, error => { return Promise.reject(error) }) service.interceptors.response.use(response => { reqCancel && RemovePendiingRequest (response.config) // Remove duplicate requests... do some thing }, error => { ... do some thing }) }Copy the code

Most of the logic is the same as in the original project, with the configuration function HTTP removed and auxiliary functions 1,2, and so on embedded.

5 adaption to general Axios

A normal project would configure AXIOS and export:

// axios.js export default axios // export // main.js import axios from '@/util/axios' // import... Prototype.$HTTP = axios this.$http.post()...Copy the code

After adaptation, we can export two request methods, one is general, one is custom

// axios.js export const reqFree = HTTP () // export const reqWithCancel = HTTP (true) // main.js import { reqFree, reqWithCancel } from '@/util/axios' ... Prototype.$HTTP = reqFree Vue.prototype.$cancelHttp = reqWithCancel $cancelhttp.post () this.$cancelhttp.post ()... // Cancel the repeated request usageCopy the code

With this configuration, it can be seamlessly embedded into existing projects without the need to adjust common requests.

conclusion

Hope to bring you help ✹~

Share is not easy, praise to encourage 🀞