小程序请求失败还需要用户手动刷新?先默默重连5次

463 阅读2分钟

有时候在访问接口会因为种种原因导致访问错误,很多时候刷新一下就好了。普通的h5页面可能很容易刷新,小程序就有些麻烦,得点击右上角的三个点,然后再点击重新进入。这样的用户体验实在太糟糕了,而且还会给人留下不稳定的印象。

既然是刷新一下就能解决的事情,那就不要再让用户动手了,小程序自己就可以在后台完成刷新,而且整个过程不会被用户感知,大幅提升用户体验。

1.封装一个try函数

首先说下思路,我们需要创建一个Promise对象,把访问接口的函数放进去执行,只有在返回200或者尝试5次之后还没返回200的情况下才会执行resolve,否则会再次执行访问函数。

步骤也很简单,首先创建一个返回promise对象的函数,姑且命名为tryFn,tryFn会接收三个值,分别是要执行的函数、参数、重复次数。

在tryFn里会定义一个函数,每次失败时会重复执行这个匿名函数,直至重复次数为0。就像这样:

function tryFn(fn, params, count) {
  return new Promise((resolve, reject) => {
    // 匿名函数,出现错误时就重复执行
    const run = () => {
      fn(params).then(resolve).catch(err => {
        if(count--) {
          console.log(`第${count}次发起请求`)
          setTimeout(() => {
            run()
          }, 1000)
        } else {
          reject(err)
        }
      })
    }
    run()
  })
}

2. 封装访问接口函数

把小程序自带的request函数封装起来,如果访问失败,或者接口没有返回200都会执行reject,也就是会让catch捕获到,然后进行重试。

function wxRequest(params) {
  return new Promise((resolve, reject) => {
    wx.request({
      url: baseUrl + params.url,
      method: params.method,
      data: params?.data || {},
      success(res) {
        // 接口没有返回200默认失败
        if(res.data.code != 200) {
          reject("访问失败")
          return
        }
        resolve(res.data)
      },
      fail(res) {
        reject(res)
      }
    })
  })
}

3.把封装好的访问函数放入tryFn

接着将访问函数作为参数放入tryFn里,封装成一个最终的request函数。

function request(params) {
  return new Promise((resolve, reject) => {
    tryFn(wxRequest, params, 5).then(res => {
      resolve(res)
    }).catch(err => {
      reject(err)
    })
  })
}

之后请求错误的情况下会每秒请求一次:

image.png