跳到主要内容

分页

Misskey 采用基于游标的分页机制。返回列表的 API 直接接收分页参数并返回 List<T>,没有包装类型。调用方负责传入参数,并通过检查返回列表的长度来判断是否还有更多页。

分页参数​

参数类型说明
sinceIdString返回比此 ID 更新的结果
untilIdString返回比此 ID 更旧的结果
sinceDateint返回比此 Unix 时间戳(毫秒)更新的结果
untilDateint返回比此 Unix 时间戳(毫秒)更旧的结果
limitint最大返回条数(通常为 1–100)
offsetint跳过指定条数(仅限支持偏移分页的 API)

并非所有 API 都支持所有参数,请参阅各端点的 API 参考文档。

基于游标的分页(按 ID)​

使用 untilId 加载更旧的页,使用 sinceId 加载更新的页。

加载更旧的页​

// 第一页 — 最新的通知
List<MisskeyNotification> page = await client.notifications.list(limit: 20);

// 下一页 — 比上一页最后一项更旧的内容
while (page.isNotEmpty) {
final oldestId = page.last.id;
final next = await client.notifications.list(
limit: 20,
untilId: oldestId,
);
if (next.isEmpty) break;
page = next;
}

加载更新的页​

// 记住上次获取到的最新 ID
String? latestId;

Future<List<MisskeyNote>> pollNewNotes() async {
final notes = await client.notes.timelineHome(
limit: 20,
sinceId: latestId,
);
if (notes.isNotEmpty) {
latestId = notes.first.id;
}
return notes;
}

基于时间戳的分页​

当需要按时间而非 ID 分页时,使用 sinceDate 和 untilDate。

final now = DateTime.now().millisecondsSinceEpoch;
final oneDayAgo = now - const Duration(days: 1).inMilliseconds;

final notes = await client.notes.timelineLocal(
limit: 30,
sinceDate: oneDayAgo,
untilDate: now,
);

基于偏移量的分页​

部分 API 支持使用 offset 而非游标参数。当无法使用游标导航时可采用此方式。

const pageSize = 50;
var offset = 0;

while (true) {
final users = await client.users.list(
limit: pageSize,
offset: offset,
);
// 处理 users...
if (users.length < pageSize) break; // 最后一页
offset += users.length;
}

判断最后一页​

没有 hasNext 标志。当返回条数少于 limit 时,即为最后一页。

const limit = 20;
final page = await client.blocking.list(limit: limit);
final isLastPage = page.length < limit;

遍历所有页​

Future<List<MisskeyNote>> fetchAllFavorites() async {
const limit = 100;
final all = <MisskeyNote>[];
String? untilId;

while (true) {
final page = await client.account.favorites(
limit: limit,
untilId: untilId,
);
all.addAll(page);
if (page.length < limit) break;
untilId = page.last.id;
}

return all;
}

自动分页辅助方法​

部分 API 提供辅助方法,自动执行上述 untilId 循环并返回惰性 Stream。目前网盘列表辅助方法支持此功能:

  • client.drive.files.listAll() — 一个文件夹中的文件
  • client.drive.folders.listAll() — 一个父文件夹中的文件夹
  • client.drive.streamAll() — 所有文件夹中的文件
await for (final file in client.drive.files.listAll(pageSize: 100)) {
print(file.name);
}

只有开始监听后才会发送请求;取消订阅会停止后续请求。结果始终按 ID 从新到旧排列;可用 maxItems 提前停止。详情请参阅网盘辅助方法。

支持分页的 API​

大多数返回列表的 API 都支持 sinceId/untilId 和 limit:

  • client.notes.timelineHome / timelineLocal / timelineGlobal
  • client.notes.list
  • client.notifications.list
  • client.account.favorites
  • client.blocking.list
  • client.mute.list
  • client.clips.list
  • client.following.requests.list
  • client.antennas.notes
  • client.channels.timeline
  • client.users.list(偏移量方式)
  • client.notes.search(偏移量方式)