Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QueryToken 的设计笔记 #5

Open
Brooooooklyn opened this issue Dec 7, 2016 · 4 comments
Open

QueryToken 的设计笔记 #5

Brooooooklyn opened this issue Dec 7, 2016 · 4 comments

Comments

@Brooooooklyn
Copy link
Contributor

Brooooooklyn commented Dec 7, 2016

按照设计,ReactiveDB 中 Database 类的 get 方法将会返回一个 QueryToken 对象,它是通过 Observable<Selector> 构造的。
这个对象并不直接包含查询的结果,而是提供 values, changes, concatcombine 四个方法供调用者使用。

QueryToken 有两个状态,初始状态和被消费状态,QueryToken 从一个状态转移到另一个状态后状态再不可改变。

valueschanges 方法都会使 QueryToken 从初始状态变为被消费状态。对一个被消费过的 QueryToken 调用这两个方法中的其中一个会抛出异常。
concat 方法则是将两个 任意状态QueryToken 合并成一个新的初始状态的 QueryToken
旧的两个 QueryToken 将会被自动销毁。

这几个方法的实现:

  • values 方法返回一个只包含一个值的 Observable
  • changes 方法则是监听一个 query 并返回一个包含 N 个值的 Observable

这两个方法使用 lovefield 可以很容易实现。

concatcombine 方法单独使用 lovefield 的接口无法直接实现。

concat 方法的行为是将两个 select, predicatelimit 部分相同,但 skip 不同的 query 合并为一个 query,并且可以对这个新的 query 进行 valueschanges 操作。(query = select + where + limit + skip)

实现的思路是:
queryselect, predicate, limitskip 部分拆分成多个属性存在 Selector 类中,取值的时候总是复制 select 与 predicate (select 是类 jQuery 的链式调用,调用过 where 后会改变自身的状态)

select.clone()
  .where(predicate.copy())
  .exec()

concat 的时候先判断 select, predicatelimit 是否相同:

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 并返回。

@Brooooooklyn Brooooooklyn changed the title QueryToken 的 设计 QueryToken 的设计笔记 Dec 7, 2016
@zensh
Copy link
Collaborator

zensh commented Dec 14, 2016

QueryToken.prototype.combine 不应该 throw error,与其它方法保持一致返回 Observable.throw。同时是不是也要对被组合的 tokens 检测 consumed?

@Brooooooklyn
Copy link
Contributor Author

combine 这里的正常返回值不是一个 Observable,而是一个新的 QueryToken 对象。而且由于 Observable 是 lazy 的,直接抛出异常有助于在调试阶段就发现问题,而放在 Observable 里面很可能运行时才会运行里面的代码,有潜在的隐患。

@zensh
Copy link
Collaborator

zensh commented Dec 14, 2016

了解。不过直接抛出异常总感觉哪里不对,因为 consumed 是运行时状态

@Saviio
Copy link
Collaborator

Saviio commented Dec 14, 2016

Let it crash

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants