javascript - 在 RxJS 中拆分可观察到的错误

标签 javascript promise rxjs rxjs5

有了 promises,我们可以使用 .then 的变体在发生错误时拆分链。下面是一个使用 fetch

的例子
fetch('http://website.com').then(
  // Perform some logic
  (response) => response.json().then(({ answer }) => `Your answer: ${answer}`),
  // Skip json parsing when an error occurs
  (error) => 'An error occurred :(',
).then(console.log);

这让我可以跳过响应处理逻辑,只响应原始提取语句中出现的错误。 RxJS 中的类似内容可能如下所示:

Observable.fromPromise(fetch('http://website.com'))
  // if I put .catch here, the result will be piped into flatMap and map
  .flatMap(response => response.json())
  .map(({ answer }) => `Your answer: ${answer}`)
  // if I put .catch here, errors thrown in flatMap and map will also be caught
  .subscribe(console.log);

由于代码状态中的注释,我不能简单地放入一个 catch 运算符,因为它与我的 promise 链的行为不同。

我知道我可以通过自定义运算符来实现它,包括具体化,或者将一个错误捕获可观察到的与这个运算符合并,但这一切似乎都是相当大的矫枉过正。是否有一种简单的方法来实现 promise 链行为?

最佳答案

实际上,如果我处于您的情况,我不会担心从 flatMapmap 捕获错误。当源 Observable 抛出错误时,它会传播给观察者。所以我在调用订阅时只使用错误处理程序(否则会重新抛出错误):

.subscribe(console.log, err => console.log('error:', err));

请注意,当源 Observable(在您的情况下是 Promise)中发生错误时,它会作为 error 通知传播,而不是作为标准的 next 通知传播。 这意味着 flatMap()map() 不会对错误消息产生任何影响。如果您使用 catch()materialize(),则两个运算符(flatMapmap)都必须是能够处理这种类型的数据(并且不会引发另一个错误)。

无论如何,您始终可以使用 share()publish() 并创建两个不同的订阅,其中每个订阅仅处理一种类型的信号:

let source = Observable.fromPromise(fetch('http://website.com')).publish();

source
  .subscribe(undefined, err => console.log(err));

source
  .flatMap(...)
  .map(...)
  .subscribe(console.log, () => {});

source.connect();

现在我有一个单独的观察者,只观察错误。

请注意,我必须使用 () => {} 进行空回调,这样错误将被静默忽略。另请注意,当使用多播(publish() 运算符)时,Subject 内部可能有一些我应该注意的特定行为,但在您的用例中可能并不重要。

关于javascript - 在 RxJS 中拆分可观察到的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43036928/

相关文章:

javascript - 在 forEach 循环中使用 async/await

node.js - Sequelize 事务中使用了多少个连接

angular - 首次单击 Rxjs 时未将值发送到 Angular 中的其他组件

javascript - 使用主题发布之前收集多个事件

javascript - ExtJS 4加载满足一定条件的列

javascript - 如何仅使用单个数组在 JavaScript 中模拟调用堆栈

javascript - 在 React 中构建一个大型多选而不是真的很慢

javascript - 如何通过 HTML 5 javascript 在本地 ipad/iphone 上存储数据并在设备上线时提交它们

javascript - RxJS 如何将一个流映射到另一个不同流的最新一个?

node.js - Node bluebird 中的 Q.ninvoke 替换