【问题标题】:Retry vue resource ajax calls using recursion使用递归重试 vue 资源 ajax 调用
【发布时间】:2017-04-15 09:56:45
【问题描述】:

如果最初失败,我正在尝试让我的 ajax 调用重试。如果初始 ajax 调用失败并超时 5 秒,它每次执行 3 次。该函数作为方法导入我的 vue 组件并在 ready() 上调用

export function getOrderStatus (order) {
  let url = `/orders/status/${order.id}`
  let promise = this.$http.get(url)

  function retry(order, path, promise, retryAttempt) {
    promise.then((response) => {
      if (response.body.status === 'success') {
        showOrderStatus()
      }
    }, (response) => {
      if (retries < 2) {
        retryAttempt++
        setTimeout(retry(order, path, promise, retryAttempt), 5000);
      } else {
        handleError()
      }
    })
  }

  retry(order, path, promise, 0)
}

组件

  import { getOrderStatus } from '../shared'

  export default {
   name: 'order-page',
   props: { order },
   methods: { getOrderStatus },
   ready() {
     this.getOrderStatus(order)
   }
 }

我不确定这是否是重试 ajax 调用的最佳方式,因此不胜感激。

【问题讨论】:

    标签: javascript ajax vue.js vue-resource


    【解决方案1】:

    您需要重构它,因为您正在缓存 promise。这里的问题是 Promise 本质上只会完成一次,解决或拒绝。因此,如果您的 $http 请求确实失败了,那么您以后对 retry() 的调用也将全部失败而不调用端点。

    试试下面的方法:

    组件如果你想跨组件共享它可以重构为一个 mixin(而不是import { getOrderStatus } from '../shared'

    data () {
        return {
            attempt: 0,
        }
    }
    
    methods: {
    
        showOrder () { // or whatever needs this
    
            this.getOrderStatus('order-123')
                .then((reponse) => this.showOrderStatus())
                .catch((reponse) => this.handleError(response))
    
        },
    
        getOrderStatus (order) {
    
            this.attempt = 0
    
            return 
                new Promise((resolve, reject) => this.callOrderEndpoint({
                    order,
                    resolve,
                    reject,
                }))
    
        },
    
        callOrderEndpoint ({ order, resolve, reject }) {
    
            const url = `/orders/status/${order.id}`
    
            this.$http
                .get(url)
                .then((response) => {
                    if (response.body.status === 'success') {
                        resolve()
                    } else {
                        reject()
                    }
                })
                .catch(response) => {
                    if (this.attempt++ < 2) {
                        setTimeout(() => 
                            this.callOrderEndpoint({ order, resolve, reject }), 
                            5000))
                    } else {
                        reject(response)
                    }
                })
    
        },
    
        showOrderStatus () {
    
            // whatever this does
    
        },
    
        handleError (response) {
    
            console.error('fail')
    
        },
    
    },
    

    我认为更好的方法是从getOrderStatus 返回一个 Promise。这将允许您将成功/失败方法移至 then/catch 方法以获得更好的结构。

    【讨论】:

    • 谢谢,我认为这是更多的结合。知道为什么我会收到Uncaught (in promise) TypeError: reject is not a function 吗?
    • 我只能假设我在上面打错字,或者在复制到您的代码时出现问题。我只是记录各种方法,看看哪里出了问题。如果我有机会,我会看看我以后是否可以构建一个演示......
    • 谢谢我真的解决了。还有一个问题,应该在哪里调用 showOrder()?我假设它取代了我原来的 ready() 函数
    • 没错,你可以随时调用
    猜你喜欢
    • 2017-05-15
    • 2014-06-14
    • 2019-08-27
    • 2010-09-15
    • 2014-10-07
    • 2016-08-25
    • 2021-02-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多