7

我有一个动作会触发一个 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

4

2 回答 2

12

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

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


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.
  })
);
于 2017-04-18T17:35:52.753 回答
0

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

...
.catch(error => return [];)
于 2018-08-17T12:19:34.247 回答