我有一个SPA正在从服务器加载一些全局/共享数据(让我们调用此APP_LOAD_OK)和页面特定数据(DASHBOARD_LOAD_OK)。我想显示加载动画,直到调度APP_LOAD_OK和DASHBOARD_LOAD_OK。
现在我在RxJS中表达了这个问题。我需要的是在每个DASHBOARD_LOAD_OK之后触发一个动作,只要有至少一个APP_LOAD_OK。像这样:
action$
.ofType(DASHBOARD_LOAD_OK)
.waitUntil(action$.ofType(APP_LOAD_OK).first())
.mapTo(...)
有人知道,我怎么能在有效的RxJS中表达它?
答案 0 :(得分:2)
您可以使用withLatestFrom
,因为它会等到两个源在发射前至少发射一次。如果您使用DASHBOARD_LOAD_OK
作为主要来源:
action$.ofType(DASHBOARD_LOAD_OK)
.withLatestFrom(action$.ofType(APP_LOAD_OK) /*Optionally*/.take(1))
.mapTo(/*...*/);
这允许您在DASHBOARD_LOAD_OK多次触发的情况下继续发光。
答案 1 :(得分:1)
我想避免实现一个新的操作符,因为我认为我的RxJS知识不够好,但事实证明它比我想象的要容易。如果有人有更好的解决方案,我会保持开放。您可以在下面找到代码。
Observable.prototype.waitUntil = function(trigger) {
const source = this;
let buffer = [];
let completed = false;
return Observable.create(observer => {
trigger.subscribe(
undefined,
undefined,
() => {
buffer.forEach(data => observer.next(data));
buffer = undefined;
completed = true;
});
source.subscribe(
data => {
if (completed) {
observer.next(data);
} else {
buffer.push(data);
}
},
observer.error.bind(observer),
observer.complete.bind(observer)
);
});
};
答案 2 :(得分:0)
如果你想在第一个APP_LOAD_OK之后收到每个DASHBOARD_LOAD_OK你可以简单地使用skipUntil:
action$ .ofType(DASHBOARD_LOAD_OK)
.skipUntil(action$.ofType(APP_LOAD_OK).Take(1))
.mapTo(...)
这只会在第一个APP_LOAD_OK之后开始发出DASHBOARD_LOAD_OK动作,之前的所有动作都会被忽略。