In the scenario encountered in the project, when fuzzy matching is triggered by the change event, multiple Ajax requests are sent within a short period of time. The last data returned may not be the last request triggered by the change event, resulting in data mismatch
The solution
The use ofAxios
To make data requests, usecancel token
Cancel the request
Official case github.com/axios/axios
// using the CancelToken.source factory
const CancelToken = axios.CancelToken
const source = CancelToken.source()
// get
axios.get('/user/1', {
cancelToken: source.token
}).catch(function (thrown) {
if(axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message)
} else {
// handle error}})// post
axios.post('/user/1', {
name: ' '
}, {
cancelToken: source.token
})
// Cancel Request parameter Optional
source.cancel('Cancel last request')
Copy the code
// use executor function
const CancelToken = axios.CancelToken
let cancel
// get
axios.get('/user/1', {
cancelToken: new CancelToken(function executor(c) {
// The executor function takes a cancel function as an argument
cancel = c
})
})
// post
axios.post('/user/1', {
name: ' '
}, {
cancelToken: new CancelToken(function executor(c) {
cancel = c
})
})
// cancel request
cancel()
Copy the code
Example of my Vue project
import axios from 'axios'
let cancel
let CancelToken
mounted() {
CancelToken = axios.CancelToken
}
FetchList cancels the last request and triggers the latest one
async fetchList() {
if(cancel) {
cancel()
}
await axios.post('/user/list', {
query: ' '
}, {
cancelToken: new CancelToken(function executor(c) {
cancel = c
})
})
}
Copy the code
Native XHR
The native XHR object calls abort() to cancel the Ajax request
let xhr
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest()
} else {
xhr = new ActiveXObject('Microsoft.XMLHTTP')
}
xhr= new XMLHttpRequest()
xhr.open('GET'.'https://api')
xhr.send()
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
// success
} else {
// error}}// Cancel the Ajax request readyState = 0
xhr.abort()
Copy the code
Axios
Source light parsingCancelToken
axios/lib/cancel/CancelToken.js
'use strict';
var Cancel = require('./Cancel');
function CancelToken(executor) {
if (typeofexecutor ! = ='function') {
throw new TypeError('executor must be a function.');
}
/** * Assign the promise's resolve method to a resolvePromise in order to use the resolvePromise method outside of the promise object to change the state of the object * /
var resolvePromise;
this.promise = new Promise(function promiseExecutor(resolve) {
resolvePromise = resolve;
});
/** * Assign the CancelToken instance to token * pass the Cancel method to executor, which calls the resolvePromise method */
var token = this;
executor(function cancel(message) {
if (token.reason) {
// Cancel the response returned
return;
}
token.reason = new Cancel(message);
// Execute the promise's resolve method to change the state
resolvePromise(token.reason);
});
}
CancelToken.prototype.throwIfRequested = function throwIfRequested() {
if (this.reason) {
throw this.reason; }}; CancelToken.source =function source() {
var cancel;
var token = new CancelToken(function executor(c) {
// c is the cancel method passed to executor in CancelToken
cancel = c;
});
return {
token: token,
cancel: cancel
};
};
module.exports = CancelToken;
Copy the code
How do I cancel the Ajax request after promise.resolve()
- will
CancelToken
Added to theaxios
的CancelToken
On the properties
// axios/lib/axios.js
axios.Cancel = require('./cancel/Cancel');
axios.CancelToken = require('./cancel/CancelToken');
axios.isCancel = require('./cancel/isCancel');
Copy the code
CancelToken
的resolve
Method triggerpromise.then
methods
// axios/lib/adapters/xhr.js
// Create an XHR object
var request = new XMLHttpRequest()
// Simulate the current Ajax request
request.open(config.method.toUpperCase(), buildURL(config.url, config.params, config.paramsSerializer), true)
if (config.cancelToken) {
config.cancelToken.promise.then(function onCanceled(cancel) {
if(! request) {return;
}
// Cancel the Ajax request
request.abort();
reject(cancel);
// Clean up request
request = null;
});
}
Copy the code