使用leancloud实现迭代查询

背景

手机APP业务中数据查询大多为滚动触底加载更多数据,如果使用传统的分页查询当遇到以下场景时就会出现数据错误:

例如某个APP页面数据展示按添加时间降序排序,默认每次请求十条数据

当用户A查询第一页数据(数据1-10)后,用户B添加了一条新数据,此时用户A操作触发加载更多数据,此时请求第二页数据,由于用户B新增了一条数据N1,按照数据按降序排列 则会把用户A查到第一页的最后一条数据10后推到第二页,此时A请求的第二页数据则会再次出现之前已经出现过的数据10,页面就会重复渲染数据10.这样的结果显示不是用户需要的。

为了解决该问题,所以采用迭代器来执行查询操作

构造迭代器

迭代器生成器介绍

LeancloudHelp 类中增加生成迭代器函数createIterator

total为要查询数据的总条数,在第一次查询后得到具体的总记录数

/**
   * 迭代查询
   * @param {*} objName 对象名
   * @param {*} params 查询参数列表 约定迭代查询需要的参数(日期类型)放在第一位
   * @param {*} sorts 排序列表 只支持单个日期类型字段排序
   * @param {*} limit 每次查询数量
   */
  static createIterator(objName, params, sorts, limit = 10) {
    let total = limit
    let i = 0
    return {
      next: async (lastCreatedAt) => {
        const done = (i >= total)
        let data
        if (params) {
          params[0].value = new Date(lastCreatedAt)
        }
        await LeancloudHelp.getList(objName, params, limit, 1, sorts, i === 0).then((res) => {
          data = res.data
          if (i === 0) {
            total = res.total
          }
        }).catch((error) => {
          throw error
        })
        i += limit
        const value = done ? undefined : data
        return {
          done,
          value,
        }
      },
    }
  }
复制代码

迭代器调用

query 为页面查询方法, createIterator为要实现迭代查询的类在这里构造相关的查询参数和排序方式

首次调用query方法时要先创建迭代器对象,然后默认执行一次迭代查询。

query = () => {
    console.log('iterator', this.state.iterator)
    if (!this.state.iterator) {
      const iterator = Notice.createIterator()
      this.setState({iterator}, () => {
        console.log('iterator', this.state.iterator)
        this.state.iterator.next(new Date()).then((res) => {
          console.log(res)
          if (!res.done) {
            if (res.value.length) {
              this.setState({lastCreatedAt: res.value[res.value.length - 1].createdAt})
            }
          }
        }).catch((error) => {
          console.error(error)
        })
      })
    } else {
      this.state.iterator.next(this.state.lastCreatedAt).then((res) => {
        console.log(res)
        if (!res.done) {
          if (res.value.length) {
            this.setState({lastCreatedAt: res.value[res.value.length - 1].createdAt})
          }
        }
      }).catch((error) => {
        console.error(error)
      })
    }
  }

static createIterator(title) {
    const params = [
      {colName: 'createdAt', value: undefined, queryType: Enum.queryType.lessThan},
      {colName: 'title', value: title, queryType: Enum.queryType.contains},
    ]
    const sorts = [
      {sortWay: Enum.sortWay.descending, colName: 'createdAt'},
    ]
    const limit = 10
    return LeancloudHelp.createIterator('Notice', params, sorts, limit)
  }
}
复制代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值