Axios request to cancel – code interpretation
# introduction
In a common scenario where the search box listens for the user to enter change request data, normally we request the server for every change. Generally, the front end uses debounce and the user stops XXX ms before sending the request. However, in some extreme cases, the data of the last request does not respond, and the user changes the input again to initiate a new request. The new request responds first, while the old request responds slowly. The user displays incorrect data.
Axios Solutions
// Before each request abort the previous request
function abort() {
if (this.source) {
this.source.cancel(CANCEL_MESSAGE);
this.source = null; }}function fetchRecords() {
this.abort();
this.source = axios.CancelToken.source();
$http.post('url', params, { cancelToken: this.source.token })
.then(data= > {
this.source = null;
})
.catch(e= > {
if(! axios.isCancel(e)) {this.source = null; }}); }// CancelToken another use of CancelToken
const CancelToken = axios.CancelToken;
let cancel;
axios.get('/user/12313', {
cancelToken: new CancelToken(function executor(c) { cancel = c; })});// Cancel the request
cancel();
Copy the code
Axios requests that the requirements analysis be cancelled
Axios does this by encapsulating const XHR = new XMLHttpRequest(); Xhr.send (), which can be cancelled via xhr.abort(). From the way we used it last time, we need to implement
- Add a CancelToken object on Axios
- The CancelToken object has the source method on it. The source method returns the token attribute and the Cancel method
- Constructor of CancelToken, which can pass a callback function and assign the cancel method.
- Add the isCancel method on axios
class CancelToken {
constructor(executor) {
executor((msg) = > {
this.cancel(msg)
});
}
cancel(msg) {
this.cancelMsg = msg;
}
//
static source() {
return {
token: null.cancel: this.cancel
}
}
}
// Key point: cancel the request asynchronously,cancelToken adds a promise
// xhr.js
const { / *... * / cancelToken } = config
if (cancelToken) {
cancelToken.promise.then(reason= > {
request.abort()
reject(reason)
})
}
// cancelToken.js
class CancelToken {
constructor(executor) {
executor((msg) = > {
this.cancel(msg)
});
this.promise = new Promise(resolve= > {
this.resolvePromise = resolve; })}cancel(msg) {
// This triggers xhr.js request. Abort
this.resolvePromise(msg);
this.cancelMsg = msg;
}
//
static source() {
let cancel = null; // ** static method, cannot use this.cancel**
return {
// Remember that this token is assigned to cancelToken
token: new CancelToken((c) = > {
cancel = c
}),
cancel,
}
}
}
// There is one last isCancel requirement left
Reject (reason) is used in xhr.js
// Axios.iscancel (reason) reason is the same reference
class Cancel(a){ message? : stringconstructor(message? : string) {
this.message = message
}
}
function isCancel(reason) {
return reason instanceof Cancel
}
// cancelToken.js
class CancelToken {
constructor(executor) {
executor((msg) = > {
this.cancel(msg)
});
this.promise = new Promise(resolve= > {
this.resolvePromise = resolve; })}cancel(msg) {
IsCancel is achieved by passing new Cancel(MSG)
this.resolvePromise(new Cancel(msg));
}
static source() {
return {
token: new CancelToken(() = > {}),
cancel: this.cancel
}
}
}
Axios.isCancel
Copy the code
Note: You can cancel multiple requests using the same Cancel token
// cancelToken.js
class CancelToken {
constructor(executor) {
executor((msg) = > {
this.cancel(msg)
});
this.promise = new Promise(resolve= > {
this.resolvePromise = resolve; })}cancel(msg) {
CancelToken cancelToken cancelToken cancelToken cancelToken cancelToken cancelToken
this.reason = new Cancel(msg);
this.resolvePromise(this.reason);
}
static source() {
return {
token: new CancelToken(() = > {}),
cancel: this.cancel
}
}
}
Copy the code
conclusion
- Before developing features, be sure to analyze requirements and list function points.
- The abort call problem is handled asynchronously by passing the promise.
- Implement isCancel with Instanceof.