评论

组件化后多次网络请求并发优化处理思路

一个复杂页面会引用很多组件,如果这些组件都有获取初始数据(或配置数据)的行为,这样在页面初始化时会产生大量相同网络请求

目前项目大都通过组件化来简化单页的复杂性,后期也很容易维护;

组件封装方面,我们要求:

  • 样式独立
  • 结构独立
  • 有业务功能(网络请求等)必须在组件内完成;

这样一个复杂页面会引用很多组件,如果这些组件都有获取初始数据(或配置数据)的行为,这样在页面初始化时会产生大量相同网络请求,如下图:

虽然无伤大雅,程序也能正常进行,但是还是想把这样重复的请求统一合并下;优化后如下:

怎么优化处理呢?找了 网络请求管理器、请求合并 等相关的,但是没有合适的,这里需要防止并发重复请求;所以自己动手改造请求;

封装请求管理器类,通过类内部变量存储所有的请求记录(tasks)
check 用于检查5秒内是否有相同的请求
get 等同于 promise 封装的 wx.request,这里将去获取 set 的值
set 请求成功或失败时 set 下,tasks 里就存放了相应的结果

class rpcm {
  tasks = {}

  check(key) {
    let nt = new Date().getTime()
    if (this.tasks[key]) {
      //console.log('resSetIntervalnt',nt , this.tasks[key].timeout)
      if (nt <= this.tasks[key].timeout) {
        return true
      }
    }
    return false
  }

  get(key) {
    return new Promise((success, fail) => {
       let resSetInterval=setInterval(()=>{
         console.log('resSetInterval',key,this.tasks[key])
         if(this.tasks[key].type=='success'){
           wx.hideLoading();
           success(this.tasks[key].res)
           clearInterval(resSetInterval)
         }
         if(this.tasks[key].type=='fail'){
           wx.hideLoading();
           fail(this.tasks[key].res)
           clearInterval(resSetInterval)
         }
       },500)
    })

  }

  set(key,type='',res=null) {
    let nt = new Date().getTime()
    this.tasks[key] = {
      timeout: nt + 5000
    }
    if(type){
      this.tasks[key]['type']=type
      this.tasks[key]['res']=JSON.parse(JSON.stringify(res))
    }
  }
}

请求的处理,这里 myRequest 只是示例,请根据你的业务改造

function myRequest(url,params){
  const RMT = new rpcm()
  //cache_key  是url地址+请求参数params
  // 如果已经存在可用请求,就直接去get 请求的结果
  if (RMT.check(cache_key)) return RMT.get(cache_key)

  RMT.set(cache_key)// 请求管理器中创建一个请求占用
  return new Promise((success, fail) => {
      wx.request({
        url: url,
        method: 'POST',
        data: params,
        success: function (res) {
          success(res.data);
          //将返回结果存入请求管理器
          RMT.set(cache_key,'success',res.data)
        },
        fail: function (res) {
          fail(res);
          //将返回结果存入请求管理器
          RMT.set(cache_key,'fail',res)
        },
        complete: function () {
          wx.hideLoading();
        }
      })
    })
  }

这样在5秒内多次调用 myRequest , 相同的url和参数就只会发起一次请求,其它请求会去等待首次请求的返回结果;

为什么多次请求不能直接忽略掉呢?每个请求之后都有自己的业务要做,不能简单的忽略!

点赞 0
收藏
评论
登录 后发表内容