检测异步系统中的结束事件

时间:2016-01-22 12:39:50

标签: javascript rxjs

我正在用RxJS写一些后端内容。一切都完成后我需要提出一些事件。

1)架构涉及Subject s所以onCompleted事件自然不会发生。它可以手动发射,但为了做到这一点,我需要依赖于某些END事件......循环圆圈。

2)架构有pending$ Observable,可以跟踪待处理的任务。 不幸的是,由于系统的异步性质,这种状态可以被清空几次,因此它本身的“空虚”不能用作END指示符。

这是我的解决方案,这是一个非常黑客,因为它需要显式的间隔常数。

import {Observable, Subject} from "rx";

let pendingS = new Subject();
let pending$ = pendingS
  .startWith(new Set())
  .scan((memo, [action, op]) => {
    if (action == "+") {
      memo.add(op);
      return memo;
    } else if (action == "-") {
      memo.delete(op);
      return memo;
    } else {
      return memo;
    }
  }).share();

let pendingDone$ = pending$ // a guess that
  .debounce(2000) // if nothing happens within 2 sec window
  .filter(pending => !pending.size); // and nothing is pending => we're done

pendingDone$.subscribe(function () {
  console.log("pendingDone!");
});

setTimeout(function () {
  pendingS.onNext(["+", "op1"]);
  pendingS.onNext(["+", "op2"]);
  pendingS.onNext(["+", "op3"]);
  pendingS.onNext(["-", "op2"]);
  pendingS.onNext(["-", "op1"]);
  pendingS.onNext(["-", "op3"]);
}, 100);

setTimeout(function () {
  pendingS.onNext(["+", "op4"]);
  pendingS.onNext(["-", "op4"]);
}, 500);

这个(非常普遍的)问题有更优雅的解决方案吗?

1 个答案:

答案 0 :(得分:1)

到目前为止,我已经找到了3个方法。

1)"闲置超时"

// next event
let pendingDone$ = pending$
  .debounce(2000)
  .filter(pending => !pending.size);

// next + completed events
let pendingDone$ = pending$
  .filter(pending => !pending.size)
  .timeout(2000, Observable.just("done"));

2)"同步设置,异步未设置"

如果挂起的删除被挂起到下一个事件循环迭代,则下一个挂起的任务应该在此之前,删除" pending为空"时间条件。

pendingS.onNext(["+", "op"]);
// do something
setImmediate(() => 
  pendingS.onNext(["-", "op"]);
);

pendingDone$
  .filter(state => !state.size)
  .skip(1); // skip initial empty state

3)调度程序(?)

它似乎可以通过调度程序获得类似的结果,但这可能是一种非传统的用法,所以我不会深入研究这个方向。