zoukankan      html  css  js  c++  java
  • 小程序下滑分页获取数据封装

    可能情况:

    1、一条数据没有

    2、到最后一页

    3、请求状态: 正在加载、加载完成、没有更多数据

    4、上滑触底,获取数据,应避免重复发送请求,所以使用数据锁

    5、防抖和节流:还可以禁用、倒计时、模态等方式防止重复发送请求

    思路:

    1、判断是否还有数据

    2、设置锁,锁开正常获取数据,锁关,证明还在请求数据,后面点击操作不做处理

    3、设置一个属性,作为判断是否是最后一页的标识,

    4、设置一个获取实时url的属性,因为每次请求的数据的页码都不一样,所以整个url都不一样,需要获取到最新的url

    5、发送请求,返回结果为空,返回数据一个空对象,返回结果非空,判断是否是最后一页,并设置最后一页的属性值是true/false

    6、如果还有数据,请求的起始条数加上每次获取的条数

    7、数据累加

    8、释放锁

    /**
     * 分页类不关心细节
     * 当用户调用类,请求需要下一页的数据,直接返回数据
     * paging 需要保存状态,所以应该要以实例化的形式供调用方调用
     */
    import {Http} from "./http";
    
    class Paging {
        start
        count
        url   //最原始的url 即没有被覆盖的url
        locker = false
        req
        moreData = true   //是否有更多数据
        accumulator  //累加的数据,每次获取新数据要和原来的数据进行累加
        // 初始方法
        // req 传入的对象,这个对象有可能不止一个url  还带有其他的参数
        /**
         * 初始构造方法
         * @param req  传入的对象,这个对象有可能不止一个url  还带有其他的参数
         * @param count  每页条数
         * @param start  从第几条开始查
         */
        constructor(req, count, start = 0) {
            this.start = start
            this.count = count
            this.req = req
            this.url = req.url
        }
    
        /**
         * 业务调用主方法
         * @returns {Promise<{item: *[], moreData: boolean, accumulator: *[], empty: boolean}|{item: *, moreData: *, accumulator: *, empty: boolean}>}
         */
        async getMoreData() {
            // 检查锁的状态,如果锁是锁住的,证明还有别的请求还没返回,其他的请求将不会进行,当请求返回结果之后,应该释放锁
    
            //判断是否还有数据
            if (!this.moreData) {
                return
            }
            // 检查是否已经锁了,也就是请求的数据是否已经返回
            if (!this._getLocker()) {
                return
            }
            // 真实请求数据
            const data = await this._actualGetData()
            // 释放锁
            this._releaseLocker()
            return data
        }
    
        /**
         * 真实发送请求、判断数据结构(异常处理等情况),返回一个对象
         * @returns {Promise<null|{item: [], moreData: boolean, accumulator: [], empty: boolean}|{item: *, moreData: *, accumulator: *, empty: boolean}>}
         * @private
         */
        async _actualGetData() {
            const req = this._getCurrentReq()
            let paging = await Http.request(req)
            if (!paging) {
                return null
            }
            if (paging.total === 0) {
                return {
                    empty: true,
                    item: [],
                    moreData: false, // 是否为最后一页的标识
                    accumulator: []
                }
            }
            this.moreData = this._moreData(paging.total_page, paging.page)
            // 判断是否还有数据
            if (this.moreData) {
                this.start += this.count
            }
            this._accumulate(paging.items)
            return {
                empty: false,
                item: paging.items,
                moreData: this.moreData, // 是否为最后一页的标识
                accumulator: this.accumulator
            }
        }
    
        /**
         * 获取当前的对象,也就是当前返回的数据对象
         * @returns {*}
         * @private
         */
        _getCurrentReq() {
            let url = this.url
            const params = `start=${this.start}&count=${this.count}`
            if (url.indexOf('?') !== -1) {
                // 当访问的地址没有包含其他的参数,如 url= v1/spu/latest + '?' + params
                url += '&' + params
            } else {
                // 当访问的地址包含其他的参数,如 url= v1/spu/latest?other=abc + '&' + params
                url += '?' + params
            }
            this.req.url = url
            return this.req
        }
    
        /**
         * 判断是否是最后一页,是否还有数据
         * @param totalPage  总页数
         * @param pageNum  当前页数,0开始计数
         * @returns {boolean}
         * @private
         */
        _moreData(totalPage, pageNum) {
            return pageNum < totalPage - 1
        }
    
        /**
         * 累加每次请求的数据
         * @param items  请求返回的数据
         * @private
         */
        _accumulate(items) {
            this.accumulator = this.accumulator.concat(items)
        }
    
        /**
         * 获取锁的状态
         * @returns {boolean}
         * @private
         */
        _getLocker() {
            // 如果锁是锁住的
            if (this.locker) {
                return false
            }
            // 如果锁是开的
            this.locker = true
            return true
        }
    
        /**
         * 释放锁
         * @private
         */
        _releaseLocker() {
            this.locker = false
        }
    }
    
    export {Paging}
  • 相关阅读:
    django orm 以列表作为筛选条件进行查询
    申请Let's Encrypt通配符HTTPS证书
    redis集群部署及踩过的坑
    MySQL的索引是什么?怎么优化?
    Session管理之超时设置和强制下线
    在MySQL中使用explain查询SQL的执行计划
    基于Docker搭建MySQL主从复制
    这些年一直记不住的 Java I/O
    高并发大容量NoSQL解决方案探索
    php 如何生成静态页
  • 原文地址:https://www.cnblogs.com/dgxblogs/p/11959221.html
Copyright © 2011-2022 走看看