目录
问题描述:
问题案例:
问题解决:
1,【原生JS】XMLHttpRequest.abort();
2,【Ajax】ajax.abort();
3,【axios】axios.CancelToken;
4,【微信小程序 】RequestTask.abort();
5,【uni-app】 requestTask.abort();
问题描述:
当前端请求发送并且响应未完成时,终止请求,不再返回数据
问题案例:
1,一些列表页接口比较慢,改变查询条件后发送查询请求,这样就和上次的查询请求形成两个异步请求,有时可能就会发生本次请求先得到响应数据,然后上一次请求后得到响应数据,这样在页面上的查询结果就会出现bug。(不是单纯的防抖和节流就能解决问题)
2,一些大文件上传,需要很久的时间,用户在中途想要终止上传
问题解决:
1,【原生JS】XMLHttpRequest.abort();
如果该请求已被发出,XMLHttpRequest.abort() 方法将终止该请求。当一个请求被终止,它的 readyState 属性将被置为0( UNSENT
)。示例:
let xhr = new XMLHttpRequest(),
method = "GET",
url = "https://developer.mozilla.org/"; // 仅为示例,并非真实接口地址。
xhr.open(method,url,true);
xhr.send();
xhr.abort(); // 终止请求
2,【Ajax】ajax.abort();
示例:
let queryTruckAjax;
if(queryTruckAjax){
queryTruckAjax.abort(); // 终止请求
}
queryTruckAjax = $.ajax({
type: "POST",
url:url,
dataType: "json",
success: function(data) {
do thing...
},error: function () {
}
});
3,【axios】axios.CancelToken;
Axios 提供了一个 CancelToken的函数,这是一个构造函数,该函数的作用就是用来取消接口请求的。利用axios请求的config参数,向axios添加一个包含cancelToken的config配置对象。示例:
可以使用 CancelToken.source
工厂方法创建 cancel token,像这样:
<body>
<div class="page" id="app">
<button @click="getMsgFirst" class="get-msg">获取数据1</button>
<button @click="getMsgSecond" class="get-msg">获取数据2</button>
<button @click="cancelGetMsg" class="cancel">取消获取</button>
</div>
<script>
import axios from 'axios'
var app = new Vue({
el: '#app',
data: {
cancelToken: null, // 这里要先初始化
source: null, // 这里要先初始化
},
created() {
this.cancelToken = axios.CancelToken;
this.source = this.cancelToken?.source();
},
methods: {
getMsgFirst () {
axios.get('/user/12345', {
cancelToken: this.source?.token
}).catch(function(thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
// 处理错误
}
});
},
getMsgSecond () {
axios.get('/user/12345', {
cancelToken: this.source?.token
}).catch(function(thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
// 处理错误
}
});
},
cancelGetMsg () {
// 取消请求(message 参数是可选的)
this.source.cancel('Operation canceled by the user.');
}
}
})
</script>
</body>
还可以通过传递一个 executor 函数到 CancelToken
的构造函数来创建 cancel token:
<body>
<div class="page" id="app">
<button @click="getMsg" class="get-msg">获取数据</button>
<button @click="cancelGetMsg" class="cancel">取消获取</button>
<ul>
<li v-for="item in items">{{item.name}}</li>
</ul>
</div>
<script>
import axios from 'axios'
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!',
items: [],
cancel: null // 这里要先初始化
},
methods: {
getMsg () {
let CancelToken = axios.CancelToken
let self = this
// 仅为示例,并非真实接口地址。
axios.get('http://jsonplaceholder.typicode.com/comments', {
cancelToken: new CancelToken(c => {
this.cancel = c
console.log(c)
// 这个参数 c 就是CancelToken构造函数里面自带的取消请求的函数,这里把该函数当参数用
})
}).then(res => {
this.items = res.data
}).catch(err => {
console.log(err)
})
},
cancelGetMsg () {
this.cancel() // 终止请求
}
}
})
</script>
</body>
实例化后的 axios 访问不到 CancelToken,但是你可以这样做:
import { Axios } from '@/common'
import axios from 'axios'
export let cancelAnalysisTask = null
// 解析excel
export const analysis = (option = {}) => Axios.post('/get/list', option, {
cancelToken: new axios.CancelToken(c => { // 这里的CancelToken原生的axios上的
cancelAnalysisTask = c
})
})
4,【微信小程序 】RequestTask.abort();
示例:
if (requestTask) {
requestTask.abort(); // 终止请求
}
let requestTask = wx.request({
url: 'test.php', //仅为示例,并非真实的接口地址
data: {
x: '',
y: ''
},
header: {
'content-type': 'application/json' // 默认值
},
success (res) {
console.log(res.data)
}
})
5,【uni-app】 requestTask.abort();
如果希望返回一个 requestTask
对象,需要至少传入 success / fail / complete 参数中的一个,如果没有传入 success / fail / complete 参数,则会返回封装后的 Promise 对象。示例:
const requestTask = uni.request({
url: 'https://www.example.com/request', // 仅为示例,并非真实接口地址。
data: {
name: 'name',
age: 18
},
success: function(res) {
console.log(res.data);
}
});
// 终止请求
requestTask.abort();