RXJS实现了对可观察的阻塞

时间:2017-05-17 08:37:02

标签: angular rxjs

我是RxJS和angular2的新手,我的目标是开发一个共享函数,以防止在模型更新和将数据保存到数据库之间竞争而不使用blockui

我粗略的想法是:

初始状态是“解冻”

1. Parent send "freeze" to children
2. Child components "block" all their internal dom event queues
3. Parent wait for all outstanding async operations (including 
    children) to complete
4. Parent save model data into database
5. Parent send "unfreeze" to children, and child component unblock their queues

但不知道如何在RxJS世界中完成

(可观察的)信号 - >来自父组件的“冻结”/“解冻”

(可观察的)目标队列 - >

When "freeze", either (choice of children component)

    a. buffer all events (e.g. keystroke)
    b. drop all events (e.g. mouse click)
    c. keep last event (e.g. windows resize)

    until "unfreeze"

When "unfreeze", no buffering or filtering, forward event ASAP, until "freeze"

非常感谢

2 个答案:

答案 0 :(得分:1)

如果您想在信号“冻结”时跳过值

const signal$ = Rx.Observable.interval(1000).map(i => i % 2);
const target$ = Rx.Observable.interval(500);
const unfreeze$ = signal$.filter(even => !!even);
const freeeze$ = signal$.filter(even => !even);

target$
  .windowToggle(unfreeze$, () => freeeze$)
  .switch() 
  .subscribe(val => console.log(val));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.0/Rx.min.js"></script>

如果要在冻结值时缓冲值

const signal$ = Rx.Observable.interval(1000).map(i => i % 2);
const target$ = Rx.Observable.interval(500).publish();
const unfreeze$ = signal$.filter(odd => odd);

target$.connect();

signal$
  .concatMap(freeze => {
    return freeze
      ? target$.takeUntil(unfreeze$).toArray()
      : target$.takeUntil(signal$);
  })
  .subscribe(val => console.log(val));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.0/Rx.min.js"></script>

答案 1 :(得分:0)

您可以使用bufferToggle

http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-bufferToggle

  

将过去的值收集为数组。仅在打开emits时开始收集,并调用closingSelector函数以获取一个Observable,告知何时关闭缓冲区。

const start$ = Rx.Observable.fromEvent(document.getElementById('start'), 'click');

const stop$ = Rx.Observable.fromEvent(document.getElementById('stop'),  'click');

const clock$ = Rx.Observable.interval(1000);

clock$
  .bufferToggle(start$, ()=>stop$)
  .mergeAll()
  .subscribe(x=>console.log(x))