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

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

作者: 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