美文网首页
小程序网络封装(下)--翻页逻辑

小程序网络封装(下)--翻页逻辑

作者: Amok校长 | 来源:发表于2021-09-15 23:37 被阅读0次

2-2 防抖、截流与分页细节分析

//1.一条数据没有 空
//2.最后一页, 还有没有更多
//3.累加 1-20、21-40
//4.非分页数据: a. 正在加载 loadding b. 空
        分页数据: a.正在加载 b.加载完成 c.没有更多数据
//5.上滑页面触底  加载 避免用户重复发请求 redis
        //按钮 button--防抖和截流: 禁用、倒计时、模态loadding、数据锁
        
        //控制 start count : (ES6以后才推出class)以类为核心的思想封装✅、以函数为核心的思想封装.

2-3 Paging对象

/// 新建 utils->paging.js 文件:
class Paging{
    // 使用Paging时, 不关注细节: 嗨, 我需要下一页的数据, 你返回给我
  // 面向对象的思想
  // Paging对象的设计借鉴了Generator(生成器)
  // 因为Paging要保持状态, 所以Paging对象要以实例化的方式提供给调用方, 不能以静态的方式.  也就是new Paging
  
  start
  count
  url
  locker = false
  
  constructor(url, count=10, start=0){ //指明初始化加载的信息
    this.start = start
    this.count = count
    this.url = url
  }
  
  getMoreData(){
    //getLocker:获取锁的状态, 如果是锁着,就停止加载; 相反就加锁
    //request
    //releaseLocker 放开锁
  }
  
  getLocker(){
    if(this.locker){
      return false
    }
    this.locker = true
    return true
  }

    releaseLocker(){
    this.locker = false
  }
}

2-4 编程原则:多用return提前结束函数,少用else

switch case 替代 if else if
多用return , 少用else

2-5 Paging对象 二

class Paging{
  
  start
  count
  req //跟请求相关的Object对象
  locker = false
    url //保存原始的url, 方便以后拼接判断
  
  constructor(req, count=10, start=0){
    this.start = start
    this.count = count
    this.req = req
    this.url = req.url
  }
  
  getMoreData(){
    //getLocker:获取锁的状态, 如果是锁着,就停止加载; 相反就加锁
    if(!this._getLocker()){
      return 
    }
    //request
    this._actualGetData()
    //releaseLocker 放开锁
    this._releaseLocker()
  }
    
    // v1/spu/latest?start=0&count=10
    _actualGetData(){
    Http.request(this.req)
  }

    //获取当前的req
    _getCurrentReq(){
    let url = this.url //因为url是一个字符串, 不是对象, 不用担心引用类型的问题(后面的操作不会改变this.url的值)
    const params = `start=${this.start}&count=${this.count}`
    // url = v1/spu/latest + '?' + params
    // url = v1/spu/latest?other=abc+'&'+params
    if(url.indexOf('?') !== -1){//判断字符中是否包含 ?
        url += '&' + params
    }
    else{
      url += '?' + params
    }
    this.req.url = url 
    return this.req
  }

  _getLocker(){
    if(this.locker){
      return false
    }
    this.locker = true
    return true
  }

    _releaseLocker(){
    this.locker = false
  }
}

2-6 Paging对象 三

class Paging{
  
  start
  count
  req //跟请求相关的Object对象
  locker = false
    url //保存原始的url, 方便以后拼接判断
  moreData //当前是不是还有更多数据
  
  constructor(req, count=10, start=0){
    this.start = start
    this.count = count
    this.req = req
    this.url = req.url
  }
  
  getMoreData(){
    //getLocker:获取锁的状态, 如果是锁着,就停止加载; 相反就加锁
    if(!this._getLocker()){
      return 
    }
    //request
    this._actualGetData()
    //releaseLocker 放开锁
    this._releaseLocker()
  }

    _actualGetData(){
    const req = this._getCurrentReq()
    let paging = Http.request(req)
    if(!paging){ //如果没有返回,则返回空
      return null//在 http.js中 统一异常处理方案
    }
    
    if(paging.total === 0){
      return{
        empty: true,
        items:[],
        moreData: false,
        accumulator: []
      }
    }
    
    this.moreData = this._moreData(paging.total_page, paging.page)
    
    //HashMap: 比较简单的模型
    //class: 在js中,如果写复杂应用, 也可以考虑给这个结果单独封装定义一个class, 然后return一个class回去.  
        //适用于: 如果返回的Object对象还要包含一些方法的话, 优先建议定义一个class,再把实例化后的对象返回回去.   
        //因为class除了包含数据之外, 还可以包含方法
    
    /*要返回的数据的模型:
    return{// 直接return Object对象或class
        empty: boolean, //是不是空数据
      items: [],//当次请求到的数据
      moreData: boolean, //是不是最后一页
      accumulator: []//累加器: 累加历史请求到的所有items数据
    }
    */
  }
    
    //判断是否有moreData(更多数据)
    _moreData(totalPage, pageNum){
    // 当前页码 pageNum, 从0开始的; totalPage总共多少页.
    return pageNum < totalPage-1
  }

    _getCurrentReq(){
    let url = this.url 
    const params = `start=${this.start}&count=${this.count}`
    if(url.indexOf('?') !== -1){
        url += '&' + params
    }
    else{
      url += '?' + params
    }
    this.req.url = url 
    return this.req
  }

  _getLocker(){
    if(this.locker){
      return false
    }
    this.locker = true
    return true
  }

    _releaseLocker(){
    this.locker = false
  }
}

2-7 Paging对象 四 (最终效果)

import {Http} from "./http";
class Paging{
  
  start
  count
  req //跟请求相关的Object对象
  locker = false
    url //保存原始的url, 方便以后拼接判断
  moreData //当前是不是还有更多数据
  accumulator //累加器(对象是可以保存状态的)
  
  constructor(req, count=10, start=0){
    this.start = start
    this.count = count
    this.req = req
    this.url = req.url
  }
  
  async getMoreData(){
    if(!this.moreData){//如果没有更多数据了直接return
      return
    }
    //getLocker:获取锁的状态, 如果是锁着,就停止加载; 相反就加锁
    if(!this._getLocker()){
      return 
    }
    //request
    const data = await this._actualGetData()
    //releaseLocker 放开锁
    this._releaseLocker()
    return data
  }

    async _actualGetData(){
    const req = this._getCurrentReq()
    let paging = await Http.request(req)
    if(!paging){ //如果没有返回,则返回空
      return null//在 http.js中 统一异常处理方案
    }
    
    if(paging.total === 0){
      return{
        empty: true,
        items:[],
        moreData: false,
        accumulator: []
      }
    }
    
    this.moreData = Paging._moreData(paging.total_page, paging.page)
    if(this.moreData){
      this.start += this.count
    }
    this._accumulate(paging.items) //调用累加器
    return{
      empty: false,
      items: paging.items,
      moreData: this.moreData,
      accumulator: this.accumulator
    }
  }
    
  //操作accumulator对象
  _accumulate(items){
    this.accumulator = this.accumulator.concat(items)
  }  
    
    static _moreData(totalPage, pageNum){//判断是否有moreData(更多数据)
    return pageNum < totalPage-1
  }

    _getCurrentReq(){
    let url = this.url 
    const params = `start=${this.start}&count=${this.count}`
    if(url.indexOf('?') !== -1){
        url += '&' + params
    }
    else{
      url += '?' + params
    }
    this.req.url = url 
    return this.req
  }

  _getLocker(){
    if(this.locker){
      return false
    }
    this.locker = true
    return true
  }

    _releaseLocker(){
    this.locker = false
  }
}

export {
    Paging
}

封装完在模型model的spu-paging.js中测试:

import {Paging} from "../utils/paging"
class SpuPaging{
  static async getLatestPaging(){
    return new Paging(req:{
      url:`spu/latest`
    },count:3)
  }
}
export{
    SpuPaging
}

在页面home.js中调用:

async initBottomSpuList(){
  const paging = await SpuPaging.getLatestPaging()
  const data = paging.getMoreData()
  if(!data){
    return
  }
  ...
},

相关文章

网友评论

      本文标题:小程序网络封装(下)--翻页逻辑

      本文链接:https://www.haomeiwen.com/subject/beqrgltx.html