- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在下面的代码中,我创建了一个简单的可观察对象,它产生一个值然后完成。然后我分享那个可观察的重播最后一个项目并订阅 3 次。紧随其后的第一次,第二次在产生值(value)之前,第三次在产生值(value)并完成 observable 之后。
let i = 0;
let obs$ = Rx.Observable.create(obs => {
console.log('Creating observable');
i++;
setTimeout(() => {
obs.onNext(i);
obs.onCompleted();
}, 2000);
}).shareReplay(1);
obs$.subscribe(
data => console.log(`s1: data = ${data}`),
() => {},
() => console.log('finish s1')
);
setTimeout( () => {
obs$.subscribe(
data => console.log(`s2: data = ${data}`),
() => {},
() => console.log('finish s2')
);
}, 1000);
setTimeout( () => {
obs$.subscribe(
data => console.log(`s3: data = ${data}`),
() => {},
() => console.log('finish s3')
);
}, 6000);
这导致以下弹珠图
Actual
s1: -----1$
s2: \--1$
s3: \1$
但我希望
Expected
s1: -----1$
s2: \--1$
s3: \----2$
我能理解为什么有人想要第一个行为,但我的推理是,与我返回数字的这个例子不同,我可能会返回一个容易受到取消订阅行为影响的对象,例如数据库连接.如果上面的弹珠图表示一个数据库连接,在我调用 db.close()
的 dispose 方法中,在第三次订阅时我会有一个异常,因为我接收到一个数据库作为值被释放的处理程序。 (因为当第二个订阅完成时 refCount = 0 并且源被处置)。
这个例子还有另一个奇怪的事情,就是即使它是用第一个值并紧随其后完成,它订阅源两次(正如您可以通过重复的“创建可观察对象”看到的那样)
我知道this github issue谈论这个但我想念的是:
如何实现(在 RxJs4 和 5 中)一个共享的 observable,它可以在源 observable 尚未完成的情况下重放最后一个项目,如果它已完成(refCount = 0),则重新创建 observable。
在 RxJs5 中,我认为共享方法解决了我问题的重新连接部分,但没有解决共享部分。
在 RxJs4 中我一无所知
如果可能,我想使用现有的运算符或主题来解决这个问题。我的直觉告诉我,我必须用这样的逻辑创建一个不同的主题,但我还没有完全做到这一点。
最佳答案
shareReplay
保持相同的基础 ReplaySubject
返回的可观察对象的剩余生命周期的实例。
一次ReplaySubject
完成后,您不能再向其中添加任何值,但它仍会重播。所以……
i
来自 0
至 1
.onNext(i)
, 然后 onCompleted()
.onCompleted()
信号完成 ReplaySubject
在shareReplay
里面,这意味着从现在开始,共享的可观察对象将简单地重放它拥有的值(即 1)并完成。另一个独立的问题是,由于您共享了可观察对象,它只会调用订阅者函数一次。这意味着 i
只会增加一次。所以即使你没有 onCompleted
并杀死你的潜在ReplaySubject
,你最终不会将它增加到 2
.
一个快速判断的方法是 onNext
对比next
.您当前在示例中使用的是 RxJS 4,但是您已经使用 RxJS 5 标记了它,并且您在 RxJS 5 中发现了一个问题。RxJS 5 是测试版,是一个完全重写 RxJS 4 的新版本。 API 更改主要是为了匹配 es-observable proposal which is currently at stage 1
I've updated your example to give you your expected results
基本上,您希望为前两次调用使用共享版本的可观察对象,为第三次调用使用原始可观察对象。
let i = 0;
let obs$ = Rx.Observable.create(obs => {
console.log('Creating observable');
i++;
setTimeout(() => {
obs.onNext(i);
obs.onCompleted();
}, 2000);
})
let shared$ = obs$.shareReplay(1);
shared$.subscribe(
data => console.log(`s1: data = ${data}`),
() => {},
() => console.log('finish s1')
);
setTimeout( () => {
shared$.subscribe(
data => console.log(`s2: data = ${data}`),
() => {},
() => console.log('finish s2')
);
}, 1000);
setTimeout( () => {
obs$.subscribe(
data => console.log(`s3: data = ${data}`),
() => {},
() => console.log('finish s3')
);
}, 6000);
此外,protip:请务必为调用 clearTimeout
的自定义可观察对象返回取消语义。 .
关于javascript - 如何通过重新连接实现 shareReplay?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36753392/
这个问题在这里已经有了答案: How does Scala's apply() method magic work? (3 个回答) 9年前关闭。 假设我在 scala 中有一个 MyList 类,其
这个问题在这里已经有了答案: What is a non-capturing group in regular expressions? (18 个回答) Reference - What does
这个问题是针对嵌入式系统的! 我有以下选项来初始化一个对象: Object* o = new Object(arg); 这会将对象放入堆中并返回指向它的指针。我不喜欢在嵌入式软件中使用动态分配。 Ob
我自己搜索过,没能成功的正则表达式。 我有一个 html 文件,其中包含 [] 之间的变量我想把每一个字都写进去。 [client_name][client_company] [cl
我是 Python 新手。我不明白为什么这段代码不起作用: reOptions = re.search( "[\s+@twitter\s+(?P\w+):(?P.*?)\s+]", d
在过去 7 个月左右的时间里,我几乎一直在使用 .NET C# 进行编程。在那之前,我的大部分编程都是用 C++(从学校里学的)。在工作中,我可能需要在接下来的几个月里做一大堆 C 语言。我对 C 的
我是 RE 的新手,我正在尝试获取歌词并分离出歌词标题、和声和主唱: 下面是一些歌词的例子: [Intro] D.A. got that dope! [Chorus: Travis Scott] Ic
这可能是不可能的,但我想检查是否可以用一种简单的方式表达这样的事情: // obviously doesn't work class Foo : IFoo where T: Bar {
我们的应用程序中有“user”和“study”实体,存储在它们各自的表中。一项研究代表一种研究和已收集的数据。它们是多对多的关系,所以我们需要一个链接表:studies_users。 我们为用户分配角
将测试条件添加到 Visual Studio 2010 数据库单元测试(对于 SQL Server 2008)时,这些条件称为例如rowCountCondition1、rowCountConditio
在模拟器上,我可以从设置中卸载 SD 卡。 然后我可以将它安装到我的操作系统上,然后正常卸载它。 我一直无法弄清楚如何在模拟器上重新安装它(无需重新启动)。 提示: adb 命令 remount 是无
假设在一个分支上执行了一系列提交,但该分支尚未与主干重新同步。是否可以从提交中生成全局补丁?是否可以从一系列提交中生成“分组”补丁?如果是,如何? 最佳答案 svn diff -rXXX:YYY UR
在某些情况下,我想在我的应用程序中锁定调整大小功能,为此我尝试对属性进行数据绑定(bind),并且不允许在某些情况下更改它,但没有成功。 有没有办法这样做? 这是我不成功的尝试: XAML: Vie
当我的计算机连接多个显示器时,我可以检测它们,并根据从获取的值设置位置来向它们绘制图形 get(0, 'MonitorPositions') 但是,当我在 MATLAB 运行时断开监视器时,此属性不会
我们有一个grails应用程序,该应用程序在grails数据库中存储了各种域对象。该应用程序连接到第二个数据库,运行一些原始sql,并在表中显示结果。它基本上是一个报告服务器。 我们通过在DataSo
无法比较来自不同容器的迭代器(参见这里的示例: https://stackoverflow.com/a/4664519/225186 )(或者从技术上讲,它不需要有意义。) 这就提出了另一个问题,来自
我有以下情况: 家长 Activity : ParentActivityClass { private Intent intent; @Override public void onCreate(Bu
我经常将元素与附加功能 Hook ,例如: $('.myfav').autocomplete(); $('.myfav').datepicker(); $('.myfav').click(somefu
因此,我将 tooltipster.js 库用于工具提示,并尝试更改工具提示在不同屏幕尺寸上的默认距离。 所以这是默认的 init 的样子: $(inputTooltipTrigger).tool
我在 ARM7 嵌入式环境中工作。我使用的编译器不支持完整的 C++ 功能。它不支持的一项功能是动态类型转换。 有没有办法实现dynamic_cast<>() ? 我使用 Google 寻找代码,但到
我是一名优秀的程序员,十分优秀!