vue - axios 取消仍在pending中的接口
需求:tabs切换时,调用相同接口(参数不同)渲染图表数据。(每 3s 请求一次)存在问题:在tabs切换的时候,因为定时器的原因,接口数据仍在pending,导致切换之后的图表第一条数据仍为上一个tabs的数据解决方案:第二次请求接口时,取消上一次请求。axios官方手册第一次未结束,不允许第二次请求定义一个变量,判断此时tabs是否切换,做对应的数据渲染具体js实现:取消上一次接口请求实现细节
·
需求:
- tabs切换时,调用相同接口(参数不同)渲染图表数据。(每 3s 请求一次)
存在问题:
- 在tabs切换的时候,因为定时器的原因,接口数据仍在pending,导致切换之后的图表第一条数据仍为上一个tabs的数据
解决方案:
- 第二次请求接口时,取消上一次请求。axios官方手册
- 第一次未结束,不允许第二次请求
- 定义一个变量,判断此时tabs是否切换,做对应的数据渲染
具体js实现:
- 取消上一次接口请求
- 实现细节
import axios from 'axios'
export default {
name: 'chart',
data () {
return {
relChartData: {},
source: null
}
},
beforeDestroy () {
if (this.timer != null) {
clearInterval(this.timer)
this.timer = null
}
},
methods: {
handleUnit (type) {
switch (type) {
case 'tps':
return '次/秒'
default:
return ''
}
},
hanndleData (data, type) {
const unit = this.handleUnit(type)
const temp = {
config: {}
}
Object.keys(data.series).forEach((item) => {
temp.config[item] = {
unit
}
})
const result = { ...data, ...temp }
return result
},
async realData (type) {
// 取消上一次请求
this.cancelRequest()
await axios({
method: 'post',
url: '/user/12345',
data: { name: '小白' },
cancelToken: new axios.CancelToken((c) => {
this.source = c
})
})
.then((res) => {
// 返回数据进行操作
this.relChartData = this.hanndleData(res.data, type)
}).catch((err) => {
if (axios.isCancel(err)) {
// 请求如果被取消
console.log('Rquest canceled')
} else {
console.log(err)
}
})
},
cancelRequest () {
if (typeof this.source === 'function') {
this.source()
}
},
// 实时数据,显示类型改变时
realChartChangeRadio (type) {
this.chartType = type
if (this.timer) {
this.relChartData = {}
clearInterval(this.timer)
this.timer = null
}
this.realData(type)
this.timer = setInterval(() => {
this.realData(type)
}, 3000)
},
}
}
- 变量判断tab切换
import axios from 'axios'
export default {
name: 'chart',
data () {
return {
relChartData: {},
tabState: true // tab切换的状态
}
},
beforeDestroy () {
if (this.timer != null) {
clearInterval(this.timer)
this.timer = null
}
},
methods: {
hanndleData (data, type) {
const unit = this.handleUnit(type)
const temp = {
config: {}
}
Object.keys(data.series).forEach((item) => {
temp.config[item] = {
unit
}
})
const result = { ...data, ...temp }
return result
},
async realData (type) {
await axios.post('user/1234').then(res => {
if (this.tabState) {
this.relChartData = this.hanndleData(res.data, type)
} else {
this.tabState = true
}
}).catch(err => {
console.log(err)
})
},
// 实时数据,显示类型改变时
realChartChangeRadio (type) {
console.log('切换了')
this.chartType = type
if (this.timer) {
this.relChartData = {}
this.tabState = false
clearInterval(this.timer)
this.timer = null
}
this.realData(type)
this.timer = setInterval(() => {
this.realData(type)
}, 3000)
},
handleUnit (type) {
switch (type) {
case 'TPS':
case 'tps':
return '次/秒'
default:
return ''
}
}
}
}
-----------------------------------------------------------------------------------------------------------------------
上面的两种方案均有各自的缺陷,方案1只要在有新的请求发起的时候,就取消上一个请求,可能导致多次cancel,而页面中长时间没有数据展示;方案2只针对,接口中只有一个请求的时候,可保证切换之后的单位正常显示,当有多个pending中的请求时(即上面的tabs切换过快),还是会出现偶尔的格式错乱的情况。
因此:最好的解决方案是:提前记录所有的网络请求。在tabs切换时,取消仍在pending中的网络请求即可
实现效果:
import axios from 'axios'
export default {
name: 'chart',
data () {
return {
relChartData: {},
source: null,
requestList: [] // 记录所有的网络请求。在tabs切换时,取消仍在pending中的网络请求
}
},
beforeDestroy () {
if (this.timer != null) {
clearInterval(this.timer)
this.timer = null
}
},
methods: {
handleUnit (type) {
switch (type) {
case 'tps':
return '次/秒'
default:
return ''
}
},
hanndleData (data, type) {
const unit = this.handleUnit(type)
const temp = {
config: {}
}
Object.keys(data.series).forEach((item) => {
temp.config[item] = {
unit
}
})
const result = { ...data, ...temp }
return result
},
async realData (type) {
await axios({
method: 'post',
url: '/user/12345',
data: { name: '小白' },
cancelToken: new axios.CancelToken((c) => {
this.source = c
this.requestList.push(c)
})
})
.then((res) => {
// 返回数据进行操作
this.relChartData = this.hanndleData(res.data, type)
}).catch((err) => {
if (axios.isCancel(err)) {
// 请求如果被取消
console.log('Rquest canceled')
} else {
console.log(err)
}
})
},
// 实时数据,显示类型改变时
realChartChangeRadio (type) {
this.chartType = type
if (this.timer) {
console.log('切换了显示类型,将仍在pending中的请求全部取消')
this.relChartData = {}
// 方案2: 在切换时,取消所有的pending请求
this.requestList.forEach((cancelFunc, index) => {
cancelFunc()
})
this.requestList = []
clearInterval(this.timer)
this.timer = null
}
this.realData(type)
this.timer = setInterval(() => {
this.realData(type)
}, 3000)
},
}
}
更多推荐
已为社区贡献1条内容
所有评论(0)