-
Notifications
You must be signed in to change notification settings - Fork 6
Description
按照设计,ReactiveDB 中 Database 类的 get 方法将会返回一个 QueryToken 对象,它是通过 Observable<Selector> 构造的。
这个对象并不直接包含查询的结果,而是提供 values, changes, concat和combine 四个方法供调用者使用。
QueryToken 有两个状态,初始状态和被消费状态,QueryToken 从一个状态转移到另一个状态后状态再不可改变。
values 与 changes 方法都会使 QueryToken 从初始状态变为被消费状态。对一个被消费过的 QueryToken 调用这两个方法中的其中一个会抛出异常。
而 concat 方法则是将两个 任意状态 的 QueryToken 合并成一个新的初始状态的 QueryToken。
旧的两个 QueryToken 将会被自动销毁。
这几个方法的实现:
values方法返回一个只包含一个值的Observablechanges方法则是监听一个query并返回一个包含 N 个值的Observable
这两个方法使用 lovefield 可以很容易实现。
concat 与 combine 方法单独使用 lovefield 的接口无法直接实现。
concat 方法的行为是将两个 select, predicate 和 limit 部分相同,但 skip 不同的 query 合并为一个 query,并且可以对这个新的 query 进行 values 和 changes 操作。(query = select + where + limit + skip)
实现的思路是:
将 query 的 select, predicate, limit 和 skip 部分拆分成多个属性存在 Selector 类中,取值的时候总是复制 select 与 predicate (select 是类 jQuery 的链式调用,调用过 where 后会改变自身的状态)
select.clone()
.where(predicate.copy())
.exec()concat 的时候先判断 select, predicate 和 limit 是否相同:
const equal = selectMetas.every(m =>
m.limit === this.limit &&
m.select === this.select &&
m.predicateProvider.toString() === this.predicateProvider.toString()
)
if (!equal) throw TOKEN_CONCAT_ERR()而 concat 实质上是取两个 QueryToken limit 的总和
这样就能产生新的 Observable<Selector>,再通过这个 Observable<Selector> 产生新的 QueryToken 并返回。