竞态请求问题
竞态请求是指网络波动时,第二次请求的结果比第一次请求的结果先返回,常见于多个 Tab 页点击切换功能,如果用户点击频繁,很可能 会出现当前页面显示别的页面的数据。
解决方法
1. 交互层面解决
添加全局的 loading 遮罩,或者禁用查询按钮 ,这样的话,在第一个请求结果没返回之前不能发送第二个请求。
2. 取消请求
- axios
js
const CancelToken = axios.CancelToken
let source
// 请求的函数
function query(keyword) {
if (source) {
source.cancel('取消请求')
}
source = CancelToken.source()
return axios
.post(
'/list',
{
keyword,
},
{
cancelToken: source.token,
}
)
.catch(function (thrown) {
// 区别处理取消请求和请求错误
if (axios.isCancel(thrown)) {
// 取消请求的逻辑
} else {
// 请求错误
}
})
}- Promise
js
let doCancel
// 请求的函数
function query(keyword) {
if (doCancel) {
// 设置上一次的 Promise 设为 rejected 状态
doCancel('取消请求')
}
return new Promise(function (resolve, reject) {
// 挂载 reject 方法
doCancel = reject
const xhr = new XMLHttpRequest()
xhr.on('load', resolve)
xhr.on('error', reject)
xhr.open('POST', '/list', true)
// 发送请求条件,这里未作处理
xhr.send(null)
}).catch(function (thrown) {
// 区别处理取消请求和请求错误
if (axios.isCancel(thrown)) {
// 取消请求的逻辑
} else {
// 请求错误
}
})
}