angular - 在Angular2中,如何拦截来自observable的错误响应并将其传递给错误 channel

标签 angular rxjs

我有一个与 api 服务器交互的服务。它有 myHttpPost(data) 方法。这个方法应该:

  1. 调用 Angular 的 http.post 到服务器
  2. 如果响应状态为 200,则向订阅者提供响应的 json 内容
  3. 如果响应有不同的状态,处理响应并将处理后的错误提供给订阅者

我的方法的当前版本是:

postData(path: string, data: Object): Rx.Observable<any> {
    let json = JSON.stringify(data);
    return this.http.post(path, json)
        .map(res => res.json())
}

这不是在执行上面列表中的第 3 点,因为 map 仅在成功时调用,而不会在出错时调用。我可以通过添加更改顺序:

.catch(error => {
    let myError = prepareErrorContent(error);
    return Rx.Observable.throw(myError);
});

然后订阅者(另一个服务)收到 myError(没关系),但 rxjs 文档说明了以下关于 catch() 方法的内容:“继续一个被下一个可观察序列的异常终止的可观察序列。” 但我希望序列正常终止而不是继续。如果我像上面那样使用 catch(),那么订阅者对 postData() 的下一次调用将不起作用(它会立即返回相同的错误,而不是进行 http 调用)。我认为这是因为序列没有终止。

怎么做?

[编辑] 这是我使用此服务的订阅者方法:

 this.jsonHttp.postData(path, data)
    .subscribe(
        struct => onNext(struct),
        error => {
            let message = this.jsonHttp.extractError(error);
            onError(message)
        },
        () => onComplete ? onComplete() : null
    );

最佳答案

事实上,对于每个 HTTP 请求,都会创建并执行一个处理链。当收到响应(成功和错误)时,链就完成了。

如果执行两次请求,则它们之间没有链接。当两个请求属于同一个处理链时,您可以有一些链接。例如,当使用像 flatMapswitchMap 这样的可观察运算符时。这是一个示例:

return this.http.get(...)
        .map(res => res.json())
        .flatMap(jsonData => {
          // Can leverage the result of the previous request 
          return this.http.get(...).map(res => res.json());
        });

当发生错误时,处理链被打断并调用catch 运算符。您可以在关联的回调中返回一个可观察对象以继续处理链。它可以是经典的 Observable 或带有 Observable.throw 的错误。在 Angular2 中的 HTTP 请求上下文中,状态代码不同于 2xx 的响应被视为错误。

当返回Observable.throw时,调用订阅时指定的第二个回调。如果它是另一个可观察对象,则调用第一个回调。例如:

return this.http.get(...)
        .map(res => res.json())
        .catch(res => {
          // The error callback (second parameter) is called
          return Observable.throw(res.json());
          // The success callback (first parameter) is called
          // return Observable.of(res.json());
        });

我实现了一个 plunkr,它在没有身份验证 header 的情况下执行请求(单击按钮),因此收到 401 状态代码。再次单击时,会添加标题,因此会收到 200 状态代码。只是为了向您展示这两个请求之间没有任何关系。

查看此插件:https://plnkr.co/edit/5WwWpwjvQmJ4AlncKVio?p=preview .

关于angular - 在Angular2中,如何拦截来自observable的错误响应并将其传递给错误 channel ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36496074/

相关文章:

javascript - 如何在 Angular2 中将从父级中的 dataService 接收到的数据传递给子级

angular - 以模型驱动形式设置 primeng 下拉列表的值

javascript - Angular2 setinterval 在 dom 更改时被阻止

javascript - 如何在 Angular 6 中显示带有变化字符串的嵌套 JSON 对象

rxjs - 递归可观察

angular - 计算 ag-grid 中选定行的数量

RxJS groupBy 转多维数组

javascript - 将 React useEffect 钩子(Hook)与 rxjs mergeMap 运算符一起使用

javascript - 在订阅期间从 Observable 返回最新的发射值计数

javascript - 计数、间隔和事件的响应式扩展缓冲区