我正在用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);
这个(非常普遍的)问题有更优雅的解决方案吗?
答案 0 :(得分:1)
到目前为止,我已经找到了3个方法。
// 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"));
如果挂起的删除被挂起到下一个事件循环迭代,则下一个挂起的任务应该在此之前,删除" pending为空"时间条件。
pendingS.onNext(["+", "op"]);
// do something
setImmediate(() =>
pendingS.onNext(["-", "op"]);
);
pendingDone$
.filter(state => !state.size)
.skip(1); // skip initial empty state
它似乎可以通过调度程序获得类似的结果,但这可能是一种非传统的用法,所以我不会深入研究这个方向。