PouchDB 变更订阅指南:实时监听数据库变化
什么是变更订阅(Changes Feed)
PouchDB 作为一款优秀的客户端数据库,提供了强大的变更订阅功能(Changes Feed)。这个功能允许开发者监听数据库中发生的所有变更,包括文档的创建、修改和删除操作。变更订阅机制是 PouchDB 实现数据同步和实时应用的核心基础。
基础使用方法
要获取数据库中的所有变更记录,可以使用 changes()
方法:
db.changes({
since: 0, // 从最初开始监听
include_docs: true // 包含完整文档内容
}).then(function (changes) {
// 处理变更数据
}).catch(function (err) {
// 错误处理
});
这个调用会返回一个 Promise,解析后可以得到从数据库创建以来的所有变更记录。
关键特性说明
-
变更记录只包含叶子版本:变更订阅只会返回文档的最新版本(叶子版本),不会包含中间的修订版本。
-
变更顺序保证:变更记录按照它们被写入数据库的顺序排列,保证了时间上的先后关系。
-
文档内容包含:默认情况下,变更记录只包含文档ID、修订版本和删除标记。通过设置
include_docs: true
可以获取完整的文档内容。
分页获取变更记录
当数据库变更记录很多时,可以使用分页机制:
const pageSize = 10;
let lastSeq = 0;
function fetchNextPage() {
return db.changes({
since: lastSeq,
limit: pageSize
}).then(function (changes) {
if (changes.results.length < pageSize) {
// 已获取所有变更
} else {
lastSeq = changes.last_seq;
return fetchNextPage();
}
});
}
fetchNextPage().catch(function (err) {
// 错误处理
});
这种分页机制特别适合处理大型数据库的变更历史。
序列号(seq)与修订号(_rev)的区别
理解 seq
和 _rev
的区别对于正确使用变更订阅非常重要:
-
seq
:代表数据库全局的变更序列号,从0开始单调递增,可以看作是整个数据库的"版本号"。 -
_rev
:代表单个文档的修订版本号,格式为"数字-哈希值",仅对单个文档有意义。
需要注意的是,seq
在不同数据库实例之间没有同步关系,仅在同一数据库实例内部有意义。
实时变更监听
PouchDB 支持实时监听数据库变更,这是构建实时应用的基础:
db.changes({
since: 'now', // 从现在开始监听
live: true // 开启实时监听模式
}).on('change', function (change) {
// 处理变更事件
}).on('error', function (err) {
// 错误处理
});
使用 'now'
作为 since
参数的值,表示只监听从当前时刻开始的变更。
变更类型识别
变更事件分为两种主要类型:
- 文档新增/修改:
change.deleted
为false
或不存在 - 文档删除:
change.deleted
为true
可以通过以下代码进行区分:
db.changes({
since: 'now',
live: true,
include_docs: true
}).on('change', function (change) {
if (change.deleted) {
// 文档被删除
} else {
// 文档被新增或修改
if (change.doc._rev.startsWith('1-')) {
// 可能是新增文档(但不完全可靠)
}
}
});
注意事项
-
新增文档识别:虽然检查修订号是否以"1-"开头可以初步判断是否为新增文档,但在复制场景下这种方法不完全可靠,因为复制可能直接跳过初始版本。
-
冲突处理:冲突版本也会出现在变更订阅中,需要特别处理。
实际应用场景
变更订阅功能在以下场景中特别有用:
- 实时数据同步:保持UI与数据库状态同步
- 聊天应用:实时显示新消息
- 协作编辑:实时反映其他用户的修改
- 数据备份:监听变更并同步到备份存储
最佳实践建议
- 在实时监听场景中,合理设置
include_docs
选项,避免不必要的数据传输。 - 对于大型数据库,考虑使用分页机制逐步处理历史变更。
- 注意处理错误事件,避免监听中断。
- 在复制场景下,不要完全依赖修订号来判断文档操作类型。
变更订阅是 PouchDB 最强大的功能之一,掌握它可以为应用添加实时数据同步能力,极大提升用户体验。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考