【问题标题】:Return a null/empty Observable in Angular 6 with Rxjs 6使用 Rxjs 6 在 Angular 6 中返回一个空/空的 Observable
【发布时间】:2018-12-28 06:36:51
【问题描述】:

我正在使用 Rxjs 6 开发 Angular 6,而我有一个关于如果响应失败或有异常返回 null/empty Observable 的问题,这是我的假设,我的远程 api 将返回一个对象IOptionResponse,它包含一个消息字符串,可以表示为'SUCCESS'或'FAILED',它还包含一个模型,它是一个'IOption'对象数组

export interface IOptionResponse {
    message: string;
    model: IOption[];
}

这是我的服务方法名称,它将返回一个 IOption 数组的 Observable,它是我的远程 API 结果的“模型”

loadIOptionMembersRelationship(): Observable<IOption[]> {
    return this.httpClient.get<IOptionResponse>('${environment.apiUrl}/api/member/XXX')
        .map(
            (response) => {
                console.log(response);
                // if response.message is success, return IOption[] model
                if (response.message == responseMessage.Success) {
                    return response.model;
                }
                else {
                    // return Observable.empty<IOption[]>(); failed
                    // return new Observable.empty<IOption[]>(); failed
                    // return new EmptyObservable<IOption[]>(); failed
                    // return new Observable<IOption[]>.from([]); failed
                    // Otherwise return a NULL/EMPTY Observable
                    //What should be the correct way to implement here???
                }
            }
        );
}

我已经阅读了类似的帖子here,但是我尝试了所有可能的解决方案,但它们都不起作用,我不确定是因为发布的解决方案已过时,还是可能在 rxjs 中更改了某些方法6 或者可能是打字稿问题...

【问题讨论】:

  • 这取决于你想如何对这样的“失败”做出反应。您可以抛出一个错误,这将允许您(以及您的方法的所有订阅者)使用正常的 catchError(...) 来处理它。一个空的 Observable 或一个内容为“未定义”的 Observable 将遍历整个流,每张地图,每一次点击,一切。所有这些地方都必须知道如何处理这个“空”的 Observable。如果它是一个错误,让它响起并抛出一个错误,你可以稍后在事件流中捕获
  • map 的返回值不应该是一个 observable,所以只需 return null 就会用一个 null 值来完成 observable。如果你想在出错的情况下终止 observable 为空,你应该使用 flatMap 或 switchMap 或类似的,它只是 empty() 来终止 observable 而不返回任何东西,或者of(null) 返回一个空值.

标签: typescript rxjs angular6 rxjs6


【解决方案1】:

如果你想在使用 Rxjs6 时返回一个空的 Observable 数组,你需要...

import { of } from 'rxjs';

然后你想返回 类型的空 Observable 数组...

return of<IOption[]>([]);

【讨论】:

  • 这是我 Observable.of([]) Variant in Angular2 的确切解决方案,现在适用于 Angular 7。有时,您只想返回一个空数组,如果你无法获取任何东西。
【解决方案2】:

您关心FAILED 的结果吗?如果你不这样做(这是非常正确的,因为你想发出一个空的 Obersavble),你可以简单地过滤它。那么你就不需要显式地发出一个空的 Observable:

 loadIOptionMembersRelationship(): Observable<IOption[]> {
    return this.httpClient.get<IOptionResponse>('${environment.apiUrl}/api/member/XXX')
        .filter(response => response.message === responseMessage.Success) //only emit those response whose message is SUCCESS
        .map(response => response.model);
}

显式返回 empty Observable 将终止流,这可能是也可能不是您想要的,具体取决于您的实现。

【讨论】:

    【解决方案3】:

    您提到的帖子中的所有解决方案都不会触发“下一个”回调,您的工作流程将无法正常工作。做就行了

    return;
    

    但在这种情况下,您将丢失错误信息。我认为最好的方法是关注

    throw new Error("Failed to get the model...");
    

    【讨论】:

      【解决方案4】:
      public yourMethod() {
          return new Observable<SomeType[]>((observer) => {
            return observer.next(null); //when you want to return NULL/Empty.
            observer.next(ActualReturnValue); //When you want to return actual value.
          });
        }
      

      调用方法

      this.yourMethod().subscribe(response=> {
        if(response)
              //CODE
        else
              //CODE
              
      },error => {
          console.log(error);        
      });
      

      【讨论】:

        【解决方案5】:

        当使用map() 时,您可以根据其源可观察对象转换新可观察对象发出的数据。您遇到的问题是您尝试返回 empty Observable,尽管您的 Observable 应该返回 IOptionsResponse 类型的值。所以你的 Observable 是基于你的代码Observable&lt;IOptionsResponse | Observable&lt;IOptionsResponse&gt;&gt;。您可以在 else 中返回 null 或 undefined。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-10-20
          • 2019-02-28
          • 2018-11-26
          • 1970-01-01
          相关资源
          最近更新 更多