返回一个空的可观察对象。

263

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()返回true时发出请求,否则在subscribe()函数上会出现错误subscribe is not defined。那么我该如何返回一个空的Observable呢?
this.collection.more().subscribe(
  (res) => {
    console.log(res);
  }, (err) => {
    console.log(err);
  }
);
15个回答

198

使用 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 完成可观察对象,因此它不会在您的流中触发 next,而只是完成。 因此,如果您使用了 tap,它们可能无法按您的意愿触发(请参见下面的示例)。

of({}) 则创建一个 Observable 并发出值为 {} 的下一个事件,然后完成 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();

5
我相信你可以只使用 of() 来完成。 - Matthijs Wessels
2
of('foo') 会立即发出并完成可观察对象。https://rxviz.com/v/0oqMVW1o - SimplGy
1
@SimplGy 是的,你说得对,我犯了错误,使用 take(1) 已经移除了,以便得到更好的答案。@MatthijsWessels,是和不是,我现在刚测试过,如果你使用 of(),它会返回一个完整的可观察对象,而不会发出 next - Stephen Lautier
3
"empty is now deprecated, use EMPTY instead"的意思是:“empty”已经过时了,应该改用“EMPTY”。这里指的是将“empty”作为常量而不是方法使用(请参阅Simon_Weaver的答案)。请注意,此处仅为翻译,没有解释或返回其他信息。 - EriF89
5
请记住,of() 不会发出任何值。如果您想要一个值,您应该提供任何值,即使是 undefined 或 null 也可以:of(null) 发出该值(并使用 tap/subscribe 方法进行处理),而 of() 则不会。 - Maxim Georgievskiy
要注意 EMPTY.subscribe() 的关系。例如,EMPTY.subscribe(() => {console.log('test');}) 可能不会像你想象的那样工作。更多信息请参见 https://blog.novanet.no/rxjs-getting-fooled-by-empty-observables/。 - Liam

151

对于TypeScript,您可以像这样指定空可观察对象的泛型参数:

import 'rxjs/add/observable/empty' 

Observable.empty<Response>();

33
现在应该这样写:import "EmptyObservable" from "rxjs/observable/EmptyObservable";,然后使用 new EmptyObservable<Response>(); - user9315861

63

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() 不再存在。


更新指南:https://github.com/ReactiveX/rxjs/blob/master/MIGRATION.md - Simon_Weaver
如果您遇到像 empty() 函数这样的冲突,您可以说 import { empty as rxEmpty }import { empty as _empty } 然后执行 rxEmpty()_empty()。当然,这是非常不标准的做法,我并不是在推荐它,但我相信我不是唯一一个惊讶于 RxJS 认为值得将 ofempty 等函数导入我的命名空间! - Simon_Weaver
1
使用Angular时要小心,因为还有import { EMPTY } from "@angular/core/src/render3/definition";这个完全不是你想要的。因此,如果你遇到奇怪的错误,请确保你没有错误地导入它。 - Simon_Weaver
1
Observable.empty()实际上仍然存在,但已被弃用,推荐使用EMPTY - Alexander Abakumov
要注意 EMPTY.subscribe() 的关系。例如,EMPTY.subscribe(() => {console.log('test');}) 可能不会像你想象的那样工作。更多信息请参见 https://blog.novanet.no/rxjs-getting-fooled-by-empty-observables/。 - Liam

50

创建空的Observable有几种方法:

它们只是在你之后如何使用它上有所不同(它会发出什么事件: nextcomplete什么也不做),例如:

  • Observable.never() - 不发出任何事件,永远不会结束。
  • Observable.empty() - 仅发出complete事件。
  • Observable.of({}) - 发出nextcomplete事件(示例中传递了空对象文字)。

根据您的实际需求使用它。


42

在我使用 Angular2 和 rxjs 的情况下,它的工作方式是:

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

7
将其包含在import {EmptyObservable} from 'rxjs/observable/EmptyObservable';中。 - Kildareflare
我遇到了这样的错误,需要在system-config中配置什么吗?未处理的Promise拒绝:(SystemJS)XHR错误(404未找到),加载http://localhost:9190/node_modules/rxjs/Observable/EmptyObservable.js, 错误:XHR错误(404未找到),加载http://localhost:9190/node_modules/rxjs/Observable/EmptyObservable.js - user630209

32

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

在 RXJS >= 6 中

import { EMPTY } from 'rxjs'
return EMPTY;

29

是的,有一个Empty操作符。

Rx.Observable.empty();

对于TypeScript,您可以使用from

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

我得到了 Rx.Observable<{}> 无法分配给 Observable<Response> 的错误,我尝试使用 Rx.Observable<Response>.empty() 但它没有起作用。 - Murhaf Sousli
我将返回类型更改为 Observable<any>,然后它就可以工作了,谢谢伙计。 - Murhaf Sousli
2
应该是 Rx.Observable.from([]) 而不是带有 <Response>。否则会出现“表达式期望”的错误。 - Andriy Tolstoy
2
你还可以使用 Rx.Observable.of([]) - Andriy Tolstoy
1
@AndriyTolstoy 我不确定这是否等价。在 Observable.of([]) 中,会发出一个值 ([]),然后流就完成了。而在 Observable.from([]) 中,没有值被发出,流立即完成。 - Pac0
文档说明最好使用import {EMPTY} from 'rxjs'(而不是empty()方法)。我猜这是出于内存考虑(即重复使用相同的空值比创建多个空对象更好)。 - bvdb

19

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

Observable.of('');

// or
Observable.of({});

// etc

4

2
或者您也可以尝试使用ignoreElements()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接