如果最初失败,我试图让我的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呼叫的最佳方式,因此任何建议都会受到赞赏。
答案 0 :(得分:2)
您需要重构此内容,因为您正在缓存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
返回一个承诺。这将允许您将成功/失败方法移动到then / catch方法以获得更好的结构。