1.取消某个接口的请求
// 第一步,定义source
window.CancelToken = this.axios.CancelToken;
window.requestSource = window.CancelToken.source();
// 第二步,定义接口的cancelToken
this.axios.post('...', formData, {
cancelToken: window.requestSource.token
})
// 第三步,取消接口
window.requestSource.cancel('cancel upload'); // cancel upload 打印在控制台
2.取消某个指定请求
data () {
return {
requestList: []
}
}
fn () {
const CancelToken = this.axios.CancelToken;
this.axios.post('...', formData, {
cancelToken: new CancelToken(c => {
this.requestList.push({
id: 'x',
cancel: c
})
})
})
for(let i = 0; i < this.requestList.length; i++) {
if (this.requestList[i].id === 'x') {
// 取消请求
this.requestList[i].cancel();
}
}
}
3.使用abort
npm install abort-controller -S
import Controller from 'abort-controller';
fn () {
let abortController = new Controller();
fetch('...', {
method: 'POST',
signal: abortController.signal
})
// 取消请求
abortController.abort()
}
4.cancelToken 的原理
源码:
'use strict';
// var Cancel = require('./Cancel');
function Cancel(message) {
this.message = message;
}
/**
* CancelToken 用来执行取消接口操作
* 返回 this
*
* @class
* @param {Function} executor The executor function.
*/
function CancelToken(executor) {
if (typeof executor !== 'function') {
throw new TypeError('executor must be a function.');
}
var resolvePromise;
this.promise = new Promise(function promiseExecutor(resolve) {
resolvePromise = resolve;
});
var token = this;
executor(function cancel(message) {
if (token.reason) {
// 已经执行过就直接 return
return;
}
token.reason = new Cancel(message);
// 这个方法可以在外部控制 CancelToken 内部的 Promise 的返回值是成功还是失败
resolvePromise(token.reason);
});
}
/**
* 如果已经执行过,就 throw Cancel 的实例
*/
CancelToken.prototype.throwIfRequested = function throwIfRequested() {
if (this.reason) {
throw this.reason;
}
};
/**
* 返回一个对象,
* token 是 new CancelToken 得到的实例,
* cancel 是 一个方法,CancelToken 中 传入 executor 的方法,调用它就可以 cancel 当前 CancelToken 的实例
*/
CancelToken.source = function source() {
var cancel;
var token = new CancelToken(function executor(c) {
// 将 CancelToken 中 exector 方法传入的 cancel 方法的控制权拿出来
cancel = c;
});
return {
token: token,
cancel: cancel
};
};
module.exports = CancelToken;
使用的时候,先调用 axios.CancelToken.source(),拿到一个对象,里面包含了 token 和 cancel 。
token 是 CancelToken 的一个实例,可以访问内部的 Promise,cancel 则可以决定这个 promise 是成功还是失败,这样做就可以在外部控制 CancelToken 内部 promise 的返回值了。
调用 cancel 后就会触发 axios 中 promise.then 方法,源码如下:
if (config.cancelToken) {
// 执行 cancel() 会触发这里的回调
config.cancelToken.promise.then(function onCanceled(cancel) {
if (!request) {
return;
}
// 取消 request
request.abort();
reject(cancel);
// 清空 request
request = null;
});
}