使用 Axios 在 Vue.js 中取消多个 API 调用
Posted
技术标签:
【中文标题】使用 Axios 在 Vue.js 中取消多个 API 调用【英文标题】:Cancelling multiple API calls in Vue.js with Axios 【发布时间】:2018-03-11 13:06:48 【问题描述】:我正在开发一个包含多个“模块”的仪表板,每个模块都有自己的 API 调用。大多数端点都很快速,但有几个可能需要几秒钟。
我有一个日期范围的过滤选项,每次更改时我都会重新运行 API 调用数据。
问题是,如果用户在其他人加载之前不断快速更改日期范围,我不希望用户能够堆叠 API 调用。
我使用单个文件 vue 组件,并为每个 API 调用提供一个方法,然后使用一个方法对它们进行分组和调用。
watch:
dateFilter: function()
this.initStatModules();
,
methods:
getCustomers: function()
var $this = this;
return axios.get(`/api/v1/reports/$$this.team.id/stats-dashboard/customers?date=$$this.dateFilter`).then(function(response)
$this.customers = response.data;
);
,
getBookings: function()
var $this = this;
return axios.get(`/api/v1/reports/$$this.team.id/stats-dashboard/bookings`).then(function(response)
$this.bookings = response.data;
);
,
getTotalRevenue: function()
var $this = this;
return axios.get(`/api/v1/reports/$$this.team.id/services-revenue?date=$$this.dateFilter`).then(function(response)
$this.totalRevenue = response.data.data.totalRevenue;
);
,
initStatModules: function()
this.getCustomers();
this.getBookings();
this.getTotalRevenue();
我希望能够在 watch 或 initStatModules 方法中取消所有待处理的 API 请求。
查看 axios 文档:https://github.com/axios/axios#cancellation 它受支持,但我无法按照自己的意愿实现它。
谢谢!
【问题讨论】:
【参考方案1】:我建议避免调用而不是取消,Axios 说它是在草稿上实现的,在这种情况下,看起来避免调用就足够了。
我的意思是:
如果发生过滤器调用,不要让用户过滤。您还需要使用 async/await 或 Promises 来更好地控制它。
例如,一个数据属性,如:
isFiltering: false
像你一样使用承诺(这里省略你的代码,但其他方法的想法相同):
methods:
getCustomers: async function ()
var $this = this;
this.isFiltering = true;
return axios.get(`/api/v1/reports/$$this.team.id/stats-dashboard/customers?date=$$this.dateFilter`).then(function(response)
$this.customers = response.data;
$this.isFiltering = false;
);
在您的 html 中使用 isFiltering
来禁用(添加 CSS 或任何您希望的)输入。这将阻止用户更改过滤,并且看起来过滤正在执行。如果出现问题,请记住添加 .catch
部分以将 isFiltering
设置为 false。如果可用,使用.finally
会更好
if isFiltering then disable
另一种方法是使用 Lodash 中的 Throttle 或任何其他解决方案,或者在 S.O. 上建议的此实现:Simple throttle in js
该限制选项更好地避免连续调用,例如当用户输入输入时。
【讨论】:
谢谢,这是我的备份选项,但您帮助解释了它。所有过滤都是通过下拉菜单完成的,所以我现在将禁用它们。希望 API 调用足够快,不需要太多,但我知道 Chrome 已经停止了几次。 是的,我知道它是怎么回事。我确实同意,如果用户错误地选择了错误的输入(下拉选择),那么等待那么长时间会很烦人。但是 imo 阻止了它的更可测试和有保证的行为。因为我不想那么依赖取消行为。但最终它是你的电话。祝你好运=)【参考方案2】:<template>
<input type="date" :disabled="isDisabled" v-model="dateFilter">
</template>
<script>
export default
data ()
return
dateFilter: null,
modulesLoaded: 0,
isDisabled: false
,
watch:
dateFilter ()
this.initStatModules()
,
methods:
getCustomers ()
axios.get(`/api/v1/reports/$$this.team.id/stats-dashboard/customers?date=$$this.dateFilter`)
.then(response =>
this.customers = response.data
this.onModuleLoaded()
)
,
getBookings ()
axios.get(`/api/v1/reports/$$this.team.id/stats-dashboard/bookings`)
.then(response =>
this.bookings = response.data
this.onModuleLoaded()
)
,
getTotalRevenue ()
axios.get(`/api/v1/reports/$$this.team.id/services-revenue?date=$$this.dateFilter`)
.then(response =>
this.totalRevenue = response.data.data.totalRevenue
this.onModuleLoaded()
)
,
initStatModules ()
this.isDisabled = true
this.modulesLoaded = 0
this.getCustomers()
this.getBookings()
this.getTotalRevenue()
,
onModuleLoaded ()
this.modulesLoaded++
if (this.modulesLoaded === 3)
this.isDisabled = false
</script>
试试这个。
【讨论】:
您应该避免仅使用代码的答案。请提供一些解释以上是关于使用 Axios 在 Vue.js 中取消多个 API 调用的主要内容,如果未能解决你的问题,请参考以下文章