如何仅在成功的情况下通过 Observable 处理 API 服务和 return 响应中的 HTTP 错误?

How to handle HTTP errors in API service and return response through Observable only in case of success?

在我的 Angular2 应用程序中,我有一个 api.service 方法 sendRequest 应该执行以下操作:

  1. 向服务器发送请求
  2. Returns向来电者承诺(我希望来电者只获得成功响应)
  3. 如果发生错误,请在本地处理错误(引导用户登录或显示弹出窗口)

我使用 Promise 实现了它:

sendRequest(method: string, url: string, data: any) : Promise<any> {
    return this.http.request(method, url, {
        body: data,
        headers: {
            'Accept': 'application/json, text/plain, */*',
            'Authorization': 'bearer ' + token,
            'Content-Type': 'application/json;charset=UTF-8'
        }
    }).toPromise().catch((res) => this.handleError(res));
}

handleError(response: any) {
    if (response.status === 401 || response.status === 403) {
        this.tokenService.deleteToken();
        this.router.navigate(['login']);
    }
    // Show popup etc.
    ...
}

我想用 observable 替换 promise:

sendRequest(method: string, url: string, data: any) : Observable<any> {...}

请告知如何做到这一点。谢谢。

编辑 1:我找到了处理响应然后将一些结果传递给观察者的示例。那不是我需要的。如果发生错误,则根本不应通知观察者。只有在成功响应到达时才应通知观察员。如果发生错误,应仅在 api.service 内处理。

http.request return 默认情况下是一个 Observable,但您正在使用 .toPromise()

将其转换为 Promise

只需将函数的签名更改为 return Observable<any> 并删除将 Observable 转换为 Promise (.toPromise().catch((res) => this.handleError(res))) 的部分。

您还需要更改收听响应的方式(您很可能会在调用服务方法的地方有一个 then,您需要将其更改为 subscribe, 这本质上是 Observables 的等价版本。

有关如何在使用 Observable 时正确捕获异常的详细说明,请参阅

请看下面 -

sendRequest(method: string, url: string, data: any) : Observable<any>{
    return this.http.request(method, url, {
        body: data,
        headers: {
            'Accept': 'application/json, text/plain, */*',
            'Authorization': 'bearer ' + token,
            'Content-Type': 'application/json;charset=UTF-8'
        }
    }).map( ( res ) => {
      return res || {};
    } )
    .catch( this.handleError );
}



handleError(response: any) {
    if (response.status === 401 || response.status === 403) {
        this.tokenService.deleteToken();
        this.router.navigate(['login']);
    }
    // Show popup etc.
    ...
}
sendRequest(method: string, url: string, data: any) : Observable<any> {
    return this.http.request(method, url, {
        body: data,
        headers: {
            'Accept': 'application/json, text/plain, */*',
            'Authorization': 'bearer ' + token,
            'Content-Type': 'application/json;charset=UTF-8'
        }
    }).map((response: Response) => <any>response.json()).catch(this.handleError);
}

handleError(response: any) {
    if (response.status === 401 || response.status === 403) {
        this.tokenService.deleteToken();
        this.router.navigate(['login']);
    }
    // Show popup etc.
    ...
}

//get response like below
  this.yoursevice.sendRequest(resdata)
        .subscribe((resdata) => {}, 
(error) => {
            this.statusMessage =
                'Problem with the service. Please try again after sometime';
            console.error(error);
        }););