RxJS:是否有空操作可观察?

RxJS: Is there an no-op observable?

我有一个操作会触发 ajax 请求。

如果由于某种原因操作失败,我什么也不想做。不是创建一个只是 returns 之前状态的空白动作,有没有我可以执行的无操作函数?

export default function fetchMeetups(action$) {
  return action$.ofType(statusActions.START_APP)
    .mergeMap(action =>
      ajax.getJSON(`${config.API_BASE_URL}/api/v1/meetups`)
      .map(meetups => calendarActions.meetupsReceived(meetups))
    )
    .catch(error => Observable.noop())
};

我已经保存了上次打开应用程序时的聚会(使用 redux-persist),所以如果 api 请求失败,我只想让它什么都不做。

这可能吗?

我从 Rxjs 找到了这个,但我不知道如何使用它:https://xgrommx.github.io/rx-book/content/helpers/noop.html

注意:link xgrommx 引用 RxJS v4,而不是 v5 或 v6。 noop 也只是一个什么都不做的函数——而不是一个什么都不发射的 Observable,这正是我相信你正在寻找的。

也就是说,我强烈反对像这样完全吞下错误。它会使以后调试这个和其他事情变得非常非常困难。我至少会记录错误消息。


v5 带有 Observable.empty()import { empty } from 'rxjs/observable/empty';,它会产生一个 Observable,它不会发出任何东西并立即完成。

但是,接下来您可能 运行 还有一些其他的细微之处。如果您让 ajax 错误传播到 mergeMap 之外的外部运算符链,您的 Epic 将不再监听未来的操作!相反,您需要尽早捕获错误,在这种情况下,将捕获放在 mergeMap 中。我们经常称之为“隔离我们的观察者链”

export default function fetchMeetups(action$) {
  return action$.ofType(statusActions.START_APP)
    .mergeMap(action =>
      ajax.getJSON(`${config.API_BASE_URL}/api/v1/meetups`)
        .map(meetups => calendarActions.meetupsReceived(meetups))
        .catch(e => {
          console.error(e);
          return Observable.empty();
        })
    );
};

现在,每当 ajax(或 map 操作)出错时,我们都会在它传播出去之前捕获该错误,而不是切换到我们的空 Observable,它将立即完成,因此内部链现在是“完成”,但我们的 Epic 将继续倾听未来的行动。


更新:

在 v6 中 empty() 是从根 import { empty } from 'rxjs'; 导入的,或者它也可以作为单例 import { EMPTY } from 'rxjs';,可以按原样使用,你不要调用它就像你 empty() 一样。它可以被重用,因为 Observables 是惰性的并且无论如何都像工厂一样,所以 empty() 是多余的。

import { EMPTY } from 'rxjs';
import { catchError } from 'rxjs/operators'; 

// etc
source$.pipe(
  catchError(e => {
    console.error(e);
    return EMPTY; // it's not a function, use it as-is.
  })
);

由于 rxjs 也接受数组,当你不想发出任何东西时,你可以简单地提供一个空数组

...
.catch(error => return [];)