Observable不会触发onComplete

选中文字可对指定文章内容进行评论啦,绿色背景文字可以点击查看评论额。

最近在使用Observable的时候,遇到一个特别有意思的问题,那就是将两个Observable顺序合并,然后订阅的时候,发现这两个Observable并不能顺序执行,而是只有一个Observable能够发出值。

首先看看我的代码吧:

let userProfile$ = this.userCenterService.getUserProfile();
let userAccount$ = this.userCenterService.getUserAccount();
let concatUser$ = concat(userProfile$,userAccount$);
concatUser$.subscribe(v=>{
    console.log('concatUser:',v);
});

需要注意的一点就是:

1、userProfile$是一个BehaviorSubject调用asObservable()返回的一个Observable对象,userAccount$同样如此。

2、它们实际上是subject调用asObservable()返回的对象。

3、使用了concat操作符,按照道理来说应该是顺序打印出这两个对象的值才对。

实际情况就是

可以看出,虽然这个值打印了两次,实际上只是打印了userProfile$的值,而没有打印出userAccount$的值。心里顿时疑惑不解?

后来仔细想想了想concat的作用,猜测应该是第一个Observable没有完成。concat的作用请参考链接。

concat的作用是必须第一个Observable完成之后,才会订阅后面的Observable执行。

在结合这个链接(Why subscribe on BehaviourSubject asObservable never fires onComplete?)的解释:

大概的意思就是说:Subject返回的Observable不会自动完成,比如手动调用subject.complete()

我们可以反过来思考一下,subject的作用主要是用于广播给多个观察者,如果它自动完成了,那么后面发送的值肯定就无法发出来啦。

因此,这个问题的解决方案就是:如果你真的需要完成这个Observable,那么就手动找到这个Observable对应的subject,然后手动调用complete();另外也可以用其他的操作符,比如merge或者zip等等

版权声明:著作权归作者所有。

相关推荐

SQL Server可能会损坏数据库的前3名错误

SQL Server是一个令人难以置信的平台,但就像任何其他数据库一样,它容易出现纠正。 了解三个最常见的SQL Server错误以及如何解决它们。你是否在思考SQL数据的损坏?你是否知道不同的错误预示着SQL Server数据库的不健康?这篇博文我们将介绍与SQL相关的三大错误以及最佳解决方案。但首先,我们探讨一些有关数据库损坏的基本信息。什么是数据库损坏

Java :Observer和Observable废弃原因及解决方案

Observer和Observable在Java 9标记为废弃。废弃原因Observer和Observable有几个原因:1、不能序列化Observable没有实现Serializable接口,它的内部成员变量都是私有的,子类不能通过继承它来对Observable的成员变量处理。所以子类也不能序列化。参考:Why is java.util.Observable&nbs

Firebug不兼容Firefox 56

Firebug最后一个版本为Firebug 2.0.19,兼容Firefox 30 – 54。Firebug此后不在开发以及维护,它的功能将集成到 Firefox 开发者工具中。

PHP 7检查session会话是否已经启动的方法

对于PHP >= 5.4.0 , PHP 7,检查session是否已经启动,推荐使用session_status判断:if (session_status() == PHP_SESSION_NONE) { session_start();}如果 PHP < 5.4.0的版本,使用session_id()检查:if(session_id() == '') { session

MySQL设置会话变量:把查询结果赋值给变量

MySQL设置变量有两种方式:会话变量和存储过程变量。1、使用set或select直接赋值,变量名以@开头例如:set @var=1; 可以在一个会话的任何地方声明,作用域是整个会话,称为用户变量。2、以declare关键字声明的变量,只能在存储过程中使用,称为存储过程变量。例如: declare var1 int default 0; 主要用在存储过程中,或者是给存储传参数中。两者的区别是: 在

CKEditor5 Observable——属性绑定

前面我们知道了,在CK5中怎么样将一个对象设置成Observable以及Observable在UI中如何使用?属性绑定今天我们来看看如何进行可观测对象的属性绑定和重命名。首先,我们假定有两个Observable对象,所谓绑定就是将一个对象的可观测状态绑定到另一个可观测对象,如下所示:const button = new Button(); const command = editor.comman

CKEditor5 Observable——绑定多个对象或属性

上一节我们学习了如何绑定属性,今天我们继续学习绑定多个属性或者多个Observable对象。 绑定多个属性如何绑定多个属性,下面我们用代码来说明:const button = new Button(); const command = editor.commands.get( 'bold' ); button.bind( 'isOn', 'isEnabled' ).to( command

CKEditor5 Observable——装饰方法

上一节我们学习了在CK5中,如何绑定多个属性以及绑定多个Observable对象,今天我们学习如何装饰方法。 首先,我们提出一个问题,为什么会有装饰方法呢?以及什么叫做装饰?所谓装饰,就是在不改变原来方法功能的前提下,增加方法的功能,众所周知在java的IO流中,就有很多地方用到了装饰。 而在CK5中,装饰是什么意思呢?请看下面这段话:Decorating object met