使用递归重试 vue 资源 ajax 调用

Posted

技术标签:

【中文标题】使用递归重试 vue 资源 ajax 调用【英文标题】:Retry vue resource ajax calls using recursion 【发布时间】: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 调用的最佳方式,因此不胜感激。

【问题讨论】:

【参考方案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() 函数 没错,你可以随时调用

以上是关于使用递归重试 vue 资源 ajax 调用的主要内容,如果未能解决你的问题,请参考以下文章

使用 jQuery 在失败时重试 AJAX 请求的最佳方法是啥?

成功ajax重试后没有.done

在 vuejs 中重试失败的 ajax 请求

如何重试 Promise 解决 N 次,尝试之间有延迟?

java客户端调用webservice时 连接超时知道是网络原因 ,如何重试如果不重试程序就死琐了,

javascript Ajax重试