[英]How to handle errors in RxJS using Angular
I'm working on an Angular application which shows a list of items fetched from a RESTful API. 我正在使用一个Angular应用程序,该应用程序显示了从RESTful API获取的项目列表。 The content of the list depends on a query.
列表的内容取决于查询。 The query can be passed either by filling in an input field, using a submit button or by adding it to the URL as query parameter.
可以通过填写输入字段,使用提交按钮或将其添加为URL作为查询参数来传递查询。
To make sure everything runs in order and prevent asynchronous issues, I'm using RxJS . 为了确保一切正常运行并防止异步问题,我使用了RxJS 。
Now I'm wondering how I can handle errors, since they can occur in the middle of a stream, eg. 现在,我想知道如何处理错误,因为错误可能发生在流的中间,例如。 when the HTTP-request fails.
当HTTP请求失败时。
These are two Observables
, which both send a sequence of queries. 这是两个
Observables
,它们都发送查询序列。
// first observable for the submit button
submitFormObservable = $scope.$createObservableFunction('search');
// second observable for when the input value changes
inputObservable = $scope.$toObservable('query')
.map(function (change) {
return change.newValue;
});
The Observable
below triggers when the query has been changed and fetches the results from the API. 下面的
Observable
会在查询已更改时触发,并从API获取结果。
var mainStream = Rx.Observable.merge([submitFormObservable, inputObservable])
.where(function (query) {
return query && query.length > 0;
})
.debounce(400)
.distinctUntilChanged()
.select(getResultsForQuery)
.switchLatest();
Now I don't know how to handle errors when eg. 现在我不知道如何处理错误,例如。 the
getResultsForQuery
throws an error. getResultsForQuery
引发错误。 I would like to display the error instead of the results, but prevent the Observable
from handling new events. 我想显示错误而不是结果,但是阻止
Observable
处理新事件。
Currently I've solved it by creating two new streams from the Observable, one to handle the result when successful and one when an error occurs. 目前,我已经通过在Observable中创建两个新的流来解决此问题,一个流在成功时处理结果,一个在发生错误时处理结果。 The response data for when the query was invalid contains an
error
property. 查询无效时的响应数据包含
error
属性。
Success stream 成功流
// stream containing the album information from LastFm
mainStream
.filter(function (response) {
return !response.data.error;
})
.map(function (response) {
return response.data.result;
})
.subscribe(function (result) {
$scope.error = undefined;
$scope.result = result;
});
Error stream 错误流
mainStream
.filter(function (response) {
return response.data.error;
})
.map(function (response) {
return response.data;
});
.subscribe(function (error) {
$scope.result = [];
$scope.error = error;
});
I've read about throwing and catching errors , but the problem here is the stream seems to stop after the first error and doesn't trigger new events. 我已经读过有关引发和捕获错误的信息 ,但是这里的问题是流在第一个错误之后似乎停止了,并且不会触发新事件。
Using onErrorResumeNext
is described in the docs to ignore errors and make sure the stream continues after an error. 在文档中介绍了使用
onErrorResumeNext
来忽略错误,并确保流在出现错误后继续。 But I can't find a way to correctly 'handle' the error and show it to the end user. 但是我找不到正确地“处理”错误并将其显示给最终用户的方法。
Is there a recommended approach on how to handle errors in a situation like this? 在这种情况下是否有建议的方法来处理错误? Is it necessary to create two streams for this, or is it recommended to throw an exception?
为此有必要创建两个流,还是建议抛出异常?
It's important that the user knows something went wrong, and the stream doesn't stop after the first error. 重要的是,用户必须知道出了点问题,并且在第一个错误发生后流不会停止。
The issue with catching logic is that it effectively terminates the sequence before it, which is why if you use it in your top level stream it will stop after a single exception. 捕获逻辑的问题在于,它有效地终止了它之前的序列,这就是为什么如果在顶级流中使用它,它将在单个异常后停止的原因。 I would recommend that you wrap your catch logic inside of a
flatMapLatest
. 我建议您将catch逻辑包装在
flatMapLatest
。 Then you can catch on the inner stream and transform the data to conform with what your downstream observers
expect. 然后,您可以捕获内部流并转换数据以符合下游
observers
期望。
Something like this: 像这样:
var mainStream = Rx.Observable.merge([submitFormObservable, inputObservable])
.where(function (query) {
return query && query.length > 0;
})
.debounce(400)
.distinctUntilChanged()
.selectSwitch(function(input) {
return getResultsForQuery(input)
.map(function(response) {
return {result : response.data.result};
})
.catch(function(e) {
return Rx.Observable.just({error : error});
});
});
mainStream.subscribe(function(r) {
$scope.result = r.result || [];
$scope.error = r.error;
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.