• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

微信小程序的网络重试机制

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

  最近在开发微信小程序, 在测试时, 总能碰到一些诸如网络被打断啊之类的问题. 小程序是一款实时互动的小程序, 基于一系列原因, 没有使用Socket, 而是使用的是长链接. 所以对这类问题不能大意啊, 一个请求断了, 后面的实时状态就无从谈起了.

  最简单的啊, 就是对这个长链接捕获错误, 然后重试呗! 当然, 实现这个很简单, 没两行代码就搞定了. 我还做了断网之类的验证, 单单规避这个长链接的错误, 完全OK的.

  但是还有很多其他请求哇, 做断网重连的测试的时候, 能导致一些其他未知的影响(当然,不断网的情况下这些是不存在的), (个人处女座, 追求完美)于是我就决定从网络请求的底层, 写入重试机制.

  整个项目是Web短和小程序端的实时互动, 为了公用一套类库, 我对所有Web和小程序端的底层接口都做了封装, 以达到公用类库的目的, 而重试机制我只准备给小程序做, Web端是内部使用的, 出现极端情况, 让他刷新一下咯, 而且这种概率很小, 就不考虑了.

  首先描述一下我的重试机制的思路, 当任何一个请求发生错误之后, 进行捕获, 进行十次重试, 每次的时间间隔都比上次长, 十次之后, 提示用户网络故障是否要重试, 用户点是之后会再次重试十次, 依次规律, 直至网络请求成功.

const _retryTimes: number = 10;
class JeResolve {
  protected promise: Promise<NetRes<any>>
  protected _resolve: (value: NetRes<any>) => void | PromiseLike<void>;
  protected _reject: (reason: any) => void;
  protected reqOptions: RequestOptions;
  protected requestObj: RequestTask;

  protected Listener: JeSysListener = new JeSysListener(this);

  constructor() {
    this.promise = new Promise((resolve, reject) => {
      this._resolve = resolve;
      this._reject = reject;
    });
  }

  request<T>(options?: RequestOptions | undefined): IResolve<T> {
    if (options) {
      this.retryTimes = 0;
      options.url = commonService.getUrl(options.url);
      this.reqOptions = options;
      this.reqOptions.success = (res: any) => {
        this.Listener.UnListen();
        this._resolve(res);
      };
      this.reqOptions.fail = (res: any) => {
        if (this.retryTimes < _retryTimes) {
          this.retryTimes++;
          if (!this.isAbort) {
            setTimeout(() => {
              if (this.retryTimes < _retryTimes + 1 && !this.isAbort) {
                this.requestObj = uni.request(this.reqOptions);
              }
            }, 100 * this.retryTimes);
          }
        } else {
          systemService.raiseRetryTimedout();
        }
      };
      this.requestObj = uni.request(this.reqOptions);
    }
    return this;
  }

  resolve<T>(call: (res: T) => void): IAbort {
    this.promise.then(res => {
      call(res.data);
    });
    return this;
  }

  abort() {
    this.Listener.UnListen();
    this.requestObj.abort();
    this.isAbort = true;
  }

  protected retryTimes: number = 0;
  protected isAbort: boolean = false;
  onRetryedSuccess(event: SysEvent): void {
    this.retryTimes = 0;
    this.requestObj = uni.request(this.reqOptions);
  }

  onRetryedTimesout(event: SysEvent): void {
    this.retryTimes = _retryTimes;
  }
}

以上是我基于Promise自己封装的请求类, 上面很容易看懂, 最底下两个方法解释一下, 是自己分封装的全局的事件的触发以及监听.
主要逻辑:
  1、当某个请求重试超过十次之后触发请求超时的事件, 全局会对事件进行一个过滤, 上次事件没有被用户反馈之前, 多个请求接连触发超时会自动过滤掉.
  2、在用户点击确定重试之后, 会触发一个确定重试的事件, 所有失败的请求都能监听到这个事件, 开始新的十次重试.
觉得这个挺好玩的, 才写出来, 还不够完善, 感兴趣的道友批评指正.

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
微信小程序success: function(res) {} 和 success: res = {}发布时间:2022-07-18
下一篇:
封装微信小程序的全局ajax发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap