【问题标题】:RxJS: Is there an no-op observable?RxJS:有没有可观察的空操作?
【发布时间】:2017-04-18 14:21:52
【问题描述】:

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

如果操作由于某种原因失败,我什么也不想做。除了创建一个只返回先前状态的空白操作之外,还有我可以执行的无操作函数吗?

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

【问题讨论】:

    标签: rxjs redux-observable


    【解决方案1】:

    注意:指向 xgrommx 的链接引用的是 RxJS v4,而不是 v5 或 v6。 noop 也只是一个什么都不做的函数——不是一个什么都不发出的 Observable,我相信这就是你正在寻找的。​​p>

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


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

    但是,接下来您可能会遇到其他一些微妙之处。如果您让 ajax 错误传播到mergeMap 之外的外部运算符链,您的 Epic 将不再监听未来的操作!相反,您会希望尽早捕获错误,在这种情况下,通过将 catch 放在 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.
      })
    );
    

    【讨论】:

    • 感谢您的详细信息!与此相关的一个问题。我遇到了一个问题,在异步函数中返回 Observable.empty() 是返回以下错误“操作必须是普通对象。使用自定义中间件进行异步操作”。如果异步函数返回 empty(),您是否知道语法应该如何?
    • 如果您曾经将forkJoin() 与 EMPTY observables 一起使用,请小心,例如,如果您有多个 HTTP 调用,您可能会使用 forkJoin 等待所有调用完成。它将短路并立即完成。如果您需要,您可能只需要返回包装在简单结构中的响应,或者返回 null。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-30
      • 2019-12-24
      • 1970-01-01
      • 2021-09-03
      • 2019-10-18
      • 2016-05-17
      • 2017-06-11
      • 2016-10-29
      相关资源
      最近更新 更多