The WeChat applet implements paging query and encapsulates paging objects.

If the paging logic needs to be used on multiple pages, it is obviously cumbersome to write repeated code each time, so it is encapsulated into an object, because the object can save the state, so after initializing an object, you only need to call the object's A getMoreData method can query data without writing any logic. Based on this idea, the pagination object is realized.

1. The problem leads to:

When implementing the above method, the following problems should be solved:

1. Construction method:

  • req object (url, method, data)
  • start and count parameters

2. Request to lock:

In order to prevent the server from requesting data slowly, the server is locked to increase the pressure on the server, and the next request can only be made after the current request ends.

3. Splicing of urls:

What is requested is the splicing parameter of get, so when there is a ? in the url, it needs to be spliced ​​with &, and when there is no ?, the ? start= splice on.

4. Data return:

  • If null is returned, it means that the server is abnormal, faulty or the request is being locked, and the caller can return directly at the same time.
  • Unified data format, as shown in the code below, returns four parameters.

Two, paging object code:

import {
    Http
} from "./http";

class Paging {
    /*提供getMoreData的接口,外界只需要调用这个方法就可以无限次的获取更多数据
     * 1、提供构造方法,将req对象传入,包括get/post方法、data、url等信息。
     * 2、书写外部使用的getMoreData方法
     *   1.需要加锁和解锁的过程,防止用户重复发请求,只有当该条数据返回之后才能进行
     *   2.只有当还有更多数据时才会发送请求
     * 3、获取真实数据:
     *   1.确定好url,即将url拼接好,因为参数是?填上去的,但是如果前面已经有?则要使用&链接
     *   2.发送http请求,获取数据
     *   3.判断 1错误 2数据为空  返回的结果不同,错误会进入全局异常管理,空就返回对应数据结构的空值。
     *   4。计算是否还有更多数据,有的话就让start+=count
     *   5.将上面得到的数据与原数据拼接。
     *   6.返回对应的数据
     * */

    req
    count
    start
    moreDataFlag = true // 是否还有更多数据
    locker = false
    url = ''
    accumulator = []


    //构造方法
    constructor(req, count = 10, start = 0) {
        this.req = req
        this.count = count
        this.start = start
        this.url = this.req.url
    }

    //获取更多数据:
    async getMoreData() {
        //上一次请求还没结束
        if (this._isLock()) {
            return null
        }
        //没有更多数据了
        if (!this.moreDataFlag) {
            return null
        }
        const data = await this._getActualData()
        //请求结束,释放锁
        this._releaseLock()
        return data
    }

    async _getActualData() {
        //1、确定好url
        const req = this._deaReqlUrl()
        //2、发送请求
        const paging = await Http.request(req)
        if (!paging) {
            //服务器端出现了异常
            return null
        }
        //服务器没有数据了
        if (paging.total === 0) {
            return {
                empty: true,
                items: [],
                moreData: false,
                accumulator: []
            }
        }
        //计算是否还有更多数据
        this.moreDataFlag = this._accumulateMoreDataFlag(paging.total_page, paging.page)
        //存在更多数据就要更新索引
        if (this.moreDataFlag) {
            this.start += this.count
        }
        //得到返回的数据
        this._getAccumulator(paging.items)
        return {
            empty: false, //是否为空
            items: paging.items, //当前请求得到的数据
            moreData: this.moreDataFlag, // 是否还有更多数据
            accumulator: this.accumulator //之前数据+刚刚得到的数据
        }
    }

    //将新老数据拼接在一起
    _getAccumulator(items) {
        //concat函数必须要接收,不是引用类型的追加
        this.accumulator = this.accumulator.concat(items)
    }

    //计算是否还有更多数据
    _accumulateMoreDataFlag(total_page, page) {
        return page < total_page - 1 //页码从0开始
    }


    //处理url问题
    /**
     * 因为接收到的req内url需要将start和count拼接上去,所以这步就是处理url问题
     * */
    _deaReqlUrl() {
        let url = this.url
        const param = `start=${this.start}&count=${this.count}`
        //传来的req中的url类似与'/v1/spu?id=2'或'/v1/spu'
        if (url.includes('?')) {
            url += '&' + param
        } else {
            url += "?" + param
        }
        this.req.url = url
        return this.req
    }

    //加锁 默认是false
    _isLock() {
        if (!this.locker) {
            this.locker = true
            return false
        }
        return true //上锁了
    }

    //释放锁
    _releaseLock() {
        this.locker = false
    }
}

export {
    Paging
}

The http class referenced above:

import {config} from "../config/config";
import {promisic} from "./util";
//传来的url格式类似 latst/spu
class Http {
    static async request({url, data, method = 'GET'}) {
        const res = await promisic(wx.request)({
            url: `http:localhost:8080/v1/${url}`,
            method,
            data,
        })
        return res.data
    }
}

export {
    Http
}

Caller code:

    async initBottom() {
       //创建分页对象
        const paging = new Paging({
            url: "spu/latest",
            method: 'GET'
        }, 5, 0)
        //分页加载更多也需要,所以将对象保存起来
        this.paging = paging
        //获取数据
        const data = await paging.getMoreData();
        //出现异常或上锁时等情况
        if (!data) {
            return
        }
    },

Guess you like

Origin blog.csdn.net/weixin_60414376/article/details/126914100