【React Native+Appwrite】获取数据时的分页机制

一、为什么要有分页

在实战开发中,如果需要做Feed流且上拉加载更多内容,说明后端肯定有很多的数据,那么向后端获取数据的时候,总不能一次性加载所有的数据吧,这样会导致加载速度变慢,且后端数据库的压力很大。

那么我们在获取数据的时候,可以分次获取,每次获取一定数量的数据,用户上拉的时候再拉取下一页,再发起一次请求,这就是分页机制。

在Appwrite中常用的分页方式有两种:

  • 基于页码 的Offset分页
  • 基于游标 的Cursor分页。

二、Offset分页(页码式分页)

Offset分页 是基于页码的,原理是记录当前的页码page,获取数据的时候从数据集中跳过前面的offset = (page - 1) * limit 条,获取limit条数据。

优点:

  • 逻辑直观好理解,实现简单
  • 适合数据量不大、不常变动的场景

缺点:

  • 数据频繁变动的时候(增加减少数据)可能会导致缺漏和重复,因为整体的数据会偏移
  • 数据量大的时候,需要跳过大量的数据,后端在处理的时候效率会降低

使用示例:

javascript 复制代码
import { Query } from "appwrite";
​
async function fetchPage_offset(page = 1, limit = 15) {
  const offset = (page - 1) * limit;
  const res = await databases.listDocuments(DB_ID, COLLECTION_ID, [
    Query.orderDesc("$createdAt"),  //排序
    Query.limit(limit),    //限制数据数量
    Query.offset(offset),  //偏移量
  ]);
  return res; // 返回来的数据在res.documents, 数量是res.total
}
​

使用场景: 小型数据集、开发期快速验证、或者你需要精准的"页码跳转到第x页"体验。

三、Cursor分页

Cursor分页 是基于游标的,原理是每次请求都按照某个顺序取一定数量的数据(一般是按照创建时间),取完以后拿出最后一条数据的ID 作为游标,下一次请求的时候从这个游标之后继续取,这样定位准确,不会缺漏记录。

相当于看书,往看到的地方插个书签,下次再读就不会找错了。

优点

  • 性能更高,数据库不需要跳过大量记录
  • 稳定性强,在数据被频繁插入和删除时更可靠,以游标为基础,不易缺漏和重复
  • 适合无限滚动的场景

缺点

  • 需要按稳定字段排序 (通常是创建时间$createdAt 或其它有索引的字段)
  • 实现时要处理排序方向(asc/desc)和 cursor 的关系
  • 无法直接跳转到某一页

使用示例

javascript 复制代码
import { Query } from "appwrite";
​
//第一次请求 
async function fetchFirstPage_cursor(limit = 15) {  
  const res = await databases.listDocuments(DB_ID, COLLECTION_ID, [
    Query.orderDesc("$createdAt"),  //排序
    Query.limit(limit),   //取limit条数据
  ]);
  return res; // 数据在res.documents, 数量是res.total
}
​
// 获取到数据后,保存最后一条数据的ID作为游标
// const lastDocId = res.documents[res.documents.length - 1].$id;
​
​
//下一页请求
async function fetchNextPage_cursor(lastDocId, limit = 15) {
  const res = await databases.listDocuments(DB_ID, COLLECTION_ID, [
    Query.orderDesc("$createdAt"),
    Query.cursorAfter(lastDocId),  //从游标处后面找起
    Query.limit(limit),
  ]);
  return res;
}
​

注意 :cursorAfter/cursorBefore 这两个方法是基于游标,不是基于时间戳。所以在使用的时候需要和排序结合使用,先排序后按游标查找,效果更稳定。

四、总结

  • 方法选择:

    • Offset分页:数据量小,需要直接跳转到第x页的场景,实现简单
    • Cursor分页:数据量大的大部分场景,例如Feed流、评论区、聊天记录或大型数据集,效果更好,但稍微复杂
  • 分页大小(limit):为了保证首屏加载的效率,量不需要太大,可以在8~20之间

  • 游标选择 :使用 Cursor 分页时,确保排序字段稳定且有索引(如 $id或$createdAt,但Appwrite官方文档中使用的是id)。

  • 去重策略:不管使用什么方法分页,获取到新数据后,都要记得去重,以免出现重复的数据

  • 刷新(pull-to-refresh)策略:下拉刷新通常应该重新拉第一页,并替换列表数据而不是追加

相关推荐
@大迁世界8 小时前
Firefox 本地模式:localhost 再见了 ?
前端·架构
米米商聊10 小时前
同名附件为什么被 Map 覆盖?重复键与一对多索引
前端·javascript
echome88811 小时前
Python 异常处理:try、else、finally 的正确搭配
开发语言·前端·python·异常处理·编程技巧
时间的情敌11 小时前
OpenLayers 实战|Vue3 + OpenLayers 完整工程案例(加载天地图、要素、弹窗、绘制、WFS)
前端·openlayers
陈随易11 小时前
下载神器!Motrix 停更三年后重写回归
前端·后端·程序员
前端的日常12 小时前
一个人+AI做情侣食谱小程序,0 费用的服务器
前端·后端
计算机魔术师12 小时前
谷歌搜索广告踩刹车,AI广告成为救命稻草
前端
总要学点什么12 小时前
第81篇:数据可视化-PM2.5分布——让圆点的胖瘦替每座城市报出浓度
前端·信息可视化·echarts·cesium·空间分析
IT_陈寒12 小时前
Vue的v-for里用了个临时变量,页面直接挂了
前端·人工智能·后端
hunter_07613 小时前
一次 iOS 真机签名 409 的完整排查:证书、设备、描述文件为什么总是"对不上"
前端