使用 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 调用的主要内容,如果未能解决你的问题,请参考以下文章

vue.js中axios的封装(参考)

Axios-一次发出多个请求(vue.js)

使用 vue js 和 axios 上传多个文件

vue中axios怎么分服务

在 ASP.NET Core 中使用 Axios 和 Vue.JS 进行多文件上传

如何在axios vue js中添加多个参数