【问题标题】:Return an empty Observable返回一个空的 Observable
【发布时间】:2016-11-27 15:41:24
【问题描述】:

函数more() 应该从get 请求中返回Observable

export class Collection {
  public more = (): Observable<Response> => {
    if (this.hasMore()) {
      return this.fetch();
    } else {
      // return empty observable
    }
  };

  private fetch = (): Observable<Response> => {
    return this.http.get("some-url").map((res) => {
      return res.json();
    });
  };
}

在这种情况下,我只能在hasMore() 为真时发出请求,否则我在subscribe() 函数subscribe is not defined 上收到错误,如何返回一个空的 Observable?

this.collection.more().subscribe(
  (res) => {
    console.log(res);
  }, (err) => {
    console.log(err);
  }
);

【问题讨论】:

    标签: javascript typescript rxjs observable


    【解决方案1】:

    使用 RxJS 5.5+ 的新语法,变成如下:

    // RxJS 6
    import { EMPTY, empty, of } from "rxjs";
    
    // rxjs 5.5+ (<6)
    import { empty } from "rxjs/observable/empty";
    import { of } from "rxjs/observable/of";
    
    empty(); // deprecated use EMPTY
    EMPTY;
    of({});
    

    请记住一件事,EMPTY 完成了 observable,因此它不会在您的流中触发 next,而只会完成。因此,例如,如果您有 tap,它们可能无法如您所愿地触发(请参见下面的示例)。

    of({}) 创建一个Observable 并发出值为{} 的next,然后完成Observable

    例如:

    EMPTY.pipe(
        tap(() => console.warn("i will not reach here, as i am complete"))
    ).subscribe();
    
    of({}).pipe(
        tap(() => console.warn("i will reach here and complete"))
    ).subscribe();
    

    【讨论】:

    • of('foo') 会立即发出并完成 observable。 rxviz.com/v/0oqMVW1o
    • @SimplGy 是的,你是对的,我对使用 take(1) 的不利之处已删除以获得更好的答案。 @MatthijsWessels,是和否,现在刚刚测试了这个,如果你这样做 of() 将返回一个完整的 observable 而不会发出 next
    • empty 现在已弃用,请改用 EMPTY(用作常量而不是方法,请参阅 Simon_Weaver 的回答)。
    • 请记住,of() 不会发出任何值。如果你想要一个,你应该提供任何值,即使 undefined 或 null 也可以:of(null) 发出值(并使用点击/订阅方法进行处理),而 of() 不会。
    【解决方案2】:

    对于打字稿,您可以像这样指定空可观察对象的通用参数:

    import 'rxjs/add/observable/empty' 
    
    Observable.empty<Response>();
    

    【讨论】:

    • 现在应该是import "EmptyObservable" from "rxjs/observable/EmptyObservable";,然后是new EmptyObservable&lt;Response&gt;();
    【解决方案3】:

    RxJS6(未安装兼容包)

    现在有一个 EMPTY 常量和一个 empty 函数。

      import { Observable, empty, EMPTY, of } from 'rxjs';
    
      //This is now deprecated
      var delay = empty().pipe(delay(1000));     
      var delay2 = EMPTY.pipe(delay(1000));
    

    Observable.empty() 不存在了。

    【讨论】:

    • 如果您已经有诸如empty() 函数之类的冲突,您可以说import { empty as rxEmpty }import { empty as _empty },然后执行rxEmpty()_empty()。当然,这是一件非常不标准的事情,我实际上并不推荐它,但我确信我不是唯一一个对 RxJS 认为它值得导入像 ofempty 这样的函数感到惊讶的人进入我的命名空间!
    • 如果使用 Angular 要小心,因为还有 import { EMPTY } from "@angular/core/src/render3/definition"; 这完全不是你想要的。因此,如果您遇到奇怪的错误,请确保您没有错误地导入。
    • Observable.empty() 实际上是still exists,但它已被EMPTY 弃用。
    • 警惕EMPTYs 与.subscribe() 的关系。例如,EMPTY.subscribe(() =&gt; {console.log('test');}) 可能不会像您认为的那样做。更多信息在这里blog.novanet.no/rxjs-getting-fooled-by-empty-observables
    【解决方案4】:

    在我使用 Angular2 和 rxjs 的情况下,它适用于:

    import {EmptyObservable} from 'rxjs/observable/EmptyObservable';
    ...
    return new EmptyObservable();
    ...
    

    【讨论】:

    【解决方案5】:

    创建 Empty Observable 的几种方法:

    它们只是在您将如何进一步使用它方面有所不同(它将在之后发出什么事件:nextcompletedo nothing)例如:

    • Observable.never() - 不发出任何事件并且永不结束。
    • Observable.empty() - 只发出 complete
    • Observable.of({}) - 发出 nextcomplete(作为示例传递的空对象字面量)。

    根据您的确切需求使用它)

    【讨论】:

      【解决方案6】:

      是的,有Empty运营商

      Rx.Observable.empty();
      

      对于打字稿,你可以使用from:

      Rx.Observable<Response>.from([])
      

      【讨论】:

      • 我得到Rx.Observable&lt;{}&gt; 不能分配给Observable&lt;Response&gt;,我尝试分配给Rx.Observable&lt;Response&gt;.empty(),但没有成功
      • 我将返回类型更改为Observable&lt;any&gt;,它成功了,谢谢队友。
      • 应该是Rx.Observable.from([]),没有&lt;Response&gt;。否则会收到错误“预期表达式”。
      • 你也可以使用Rx.Observable.of([])
      • @AndriyTolstoy 我不确定这是否等效。在Observable.of([]) 中,发出一个值([]),然后流完成。使用Observable.from([]),不会发出任何值,流立即完成。
      【解决方案7】:

      你可以返回 Observable.of(empty_variable),例如

      Observable.of('');
      
      // or
      Observable.of({});
      
      // etc
      

      【讨论】:

        【解决方案8】:

        由于所有答案都已过时,我将在此处发布最新答案

        在 RXJS >= 6

        import { EMPTY } from 'rxjs'
        return EMPTY;
        

        【讨论】:

          【解决方案9】:

          或者你也可以试试ignoreElements()

          【讨论】:

            【解决方案10】:

            RxJS 6

            你也可以使用下面的函数:

            return from<string>([""]);
            

            导入后:

            import {from} from 'rxjs';
            

            【讨论】:

            • 这将创建一个 Observable,它将提供一个元素(一个空字符串),因此它看起来不是这个特定问题的正确答案。
            【解决方案11】:

            带着类似的问题来到这里,上面的方法对我不起作用:"rxjs": "^6.0.0",为了生成一个不发出我需要做的数据的可观察对象:

            import {Observable,empty} from 'rxjs';
            class ActivatedRouteStub {
              params: Observable<any> = empty();
            }
            

            【讨论】:

              【解决方案12】:

              试试这个

              export class Collection{
              public more (): Observable<Response> {
                 if (this.hasMore()) {
                   return this.fetch();
                 }
                 else{
                   return this.returnEmpty(); 
                 }            
                }
              public returnEmpty(): any {
                  let subscription = source.subscribe(
                    function (x) {
                     console.log('Next: %s', x);
                  },
                  function (err) {
                     console.log('Error: %s', err);
                  },
                  function () {
                     console.log('Completed');
                  });
                  }
                }
              let source = Observable.empty();
              

              【讨论】:

                【解决方案13】:

                你可以用所有不同的方式返回空的 observable,但挑战是用预期的类型返回它 - 下面是创建一个空的 observable 类型的方法 -

                intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
                    
                return next.handle(this.setHeaders(req))
                            .pipe(
                                catchError((error: HttpErrorResponse) => {
                        // you write your logic and return empty response if required
                        return new Observable<HttpEvent<any>>();
                            }));
                    }
                

                【讨论】:

                  【解决方案14】:

                  返回空 observable 的不同方式:

                  1. Observable.from({});
                  2. Observable.of({});

                  https://www.learnrxjs.io/learn-rxjs/operators/creation/empty

                  【讨论】:

                    猜你喜欢
                    • 2017-07-27
                    • 1970-01-01
                    • 2020-10-10
                    • 2018-11-21
                    • 1970-01-01
                    • 2018-12-28
                    • 2021-11-07
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多