返回一个空的Observable


166

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

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()function 上遇到错误subscribe is not defined,如何返回可观察到的空值?

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

更新资料

在RXJS 6中

import { EMPTY } from 'rxjs'

return EMPTY; 

Answers:


129

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

import 'rxjs/add/observable/empty' 

Observable.empty<Response>();

26
现在,这应该是import "EmptyObservable" from "rxjs/observable/EmptyObservable";的话new EmptyObservable<Response>();

86

使用RxJS 5.5+的新语法,结果如下:

// RxJS 6
import { empty, of } from "rxjs";

// rxjs 5.5+ (<6)
import { empty } from "rxjs/observable/empty";
import { of } from "rxjs/observable/of";

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();


1
of('foo')确实会发出并立即完成可观察的任务。rxviz.com/v/0oqMVW1o
SimplGy

@SimplGy是的,您是正确的,我为使用take(1)更好的答案而删除了它。@MatthijsWessels,是和不是,现在就进行了测试,如果您这样做,of()将返回一个完整的可观察到的信号,而不会发出next
Stephen Lautier

现在不建议使用Empty,而应使用EMPTY(用作常量而不是方法,请参见Simon_Weaver的回答)。
EriF89

请记住,of()不会发出任何值。如果您想要一个,则应提供任何值,即使为此未定义或null也可以:of(null)发出该值(以及使用tap / subscribe方法的进程),而of()则不提供。
Maxim Georgievskiy

51

RxJS6(未安装兼容软件包)

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

  import { Observable, empty, of } from 'rxjs';

  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认为值得将诸如ofand的函数导入empty到我的命名空间中!
Simon_Weaver

1
使用Angular时请多加注意,因为import { EMPTY } from "@angular/core/src/render3/definition";这完全不是您想要的。因此,如果遇到奇怪的错误,请确保不要误导入。
Simon_Weaver

Observable.empty()实际上仍然存在,但已不赞成使用EMPTY
亚历山大·阿巴库莫夫

39

就我使用Angular2和rxjs而言,它适用于:

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

7
包括在内import {EmptyObservable} from 'rxjs/observable/EmptyObservable';
Kildareflare

收到这样的错误,是否需要在system-config中配置任何内容?未处理的承诺拒绝:(SystemJS)XHR错误(404未找到)正在加载localhost:9190 / node_modules / rxjs / Observable / EmptyObservable.js 错误:XHR错误(404未找到)正在加载localhost:9190 / node_modules / rxjs / Observable / EmptyObservable。 js
user630209 '17

29

是的,有一个空运算符

Rx.Observable.empty();

对于打字稿,您可以使用from

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

Rx.Observable<{}>无法分配给Observable<Response>我,Rx.Observable<Response>.empty()但我却尝试不了
Murhaf Sousli

我将返回类型更改为Observable<any>,它起作用了,谢谢队友。
Murhaf Sousli '16

2
应该Rx.Observable.from([])没有<Response>。否则会出现错误“预期的表达式”。
安德烈·托尔斯泰

2
您也可以使用Rx.Observable.of([])
托尔斯泰

1
@AndriyTolstoy我不确定这是等效的。在中Observable.of([]),发出一个值([]),然后流完成。使用时Observable.from([]),不会发出任何值,流将立即完成。
Pac0

24

创建Empty Observable的几种方法:

它们只是在您进一步使用它的方式上有所不同(它将在nextcomplete或之后发出什么事件,do nothing例如:

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

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


12

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

Observable.of('');

// or
Observable.of({});

// etc


1

RxJS 6

您也可以从以下功能中使用:

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

导入后:

import {from} from 'rxjs';

2
这将创建一个Observable,它将提供一个元素(一个空字符串),因此对于这个特定问题,它看起来不像是正确的答案。
BrunoJCM

1

来到这里有一个类似的问题,以上内容对我不起作用:"rxjs": "^6.0.0",为了生成一个可观察的对象,它不发出我需要做的数据:

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

0

试试这个

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();
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.