1

我有一个 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 表达它?

4

3 回答 3

2

您可以使用withLatestFrom,因为它会等到两个源在发射前至少发射一次。如果您使用DASHBOARD_LOAD_OK作为主要来源:

action$.ofType(DASHBOARD_LOAD_OK)
  .withLatestFrom(action$.ofType(APP_LOAD_OK) /*Optionally*/.take(1))
  .mapTo(/*...*/);

这允许您在 DASHBOARD_LOAD_OK 多次触发的情况下继续发射。

于 2017-01-23T18:07:56.687 回答
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)
    );
  });
};
于 2017-01-23T12:32:05.547 回答
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 操作,之前的所有操作都将被忽略。

于 2017-01-23T14:01:59.080 回答