这里是一个例子。该来源被认为是半冷半热:
const subject = new Subject()
const source = of(1, 2, 3).pipe(concat(subject))
const hot = source.pipe(
share()
)
setTimeout(() => {
hot.subscribe(val => console.log(`a: ${val}`))
subject.next(6)
}, 1000)
subject.next(4)
subject.next(5)
但是输出:
a: 1
a: 2
a: 3
a: 6
这被认为是预期结果还是错误?
答案 0 :(得分:1)
是的,这是正确的结果,这就是原因:
'concat'仅在'of(1,2,3)'完成后才订阅主题。但是由于将hot.subscribe封装在setTimeout中-subject.next(4)和5不会重新发送到热订阅,因为它们在SetTimeout函数中订阅hot之前运行。
of默认情况下具有同步发射,没有延迟,因此您首先从'of'中获得1,2,3,然后从subject.next(6)中获得'6'
如果在发射和一些订阅者之间存在一些延迟,则使用“共享”是有意义的。
答案 1 :(得分:1)
这是预期的行为。可观察到的是冷的,因为直到第一个订阅者订阅它之后,它才开始产生任何东西,然后它订阅Subject
并从主题发出值。时间轴大致是这样:
subject
已创建source
已创建hot
已创建subject
发出4
subject
发出5
hot
已订阅hot
发出1
hot
发出2
hot
发出3
hot
订阅了subject
subject
发出6
hot
发出6
定义一个可观察对象只会创建一个可观察对象的蓝图,在您订阅该可观察对象之前,它实际上并不是构建的。这也意味着每次订阅时都会根据该蓝图构建一个新的可观察对象。
share
确保在第一个订阅者订阅该观察对象时,它仅构建一次。任何后续的订户将收到已经建立的可观察对象。它们之间是共享。
请注意,在订阅之前发出的任何信号都不会重复。构建后,共享的可观察对象很热,因此新订阅将仅接收订阅后发出的事件。
编辑:
假设您有一个可观察对象,它每10秒调用一次Web API:
let getFromWebApi = interval(10 * 1000).pipe(
mergeMap(_ => callWebApi())
)
接下来,假设您想在代码的五个不同位置获得这些结果,您将这样做:
// Somewhere in your code
getFromWebApi.subscribe(response => /* Handle response */);
// Somewhere else in your code
getFromWebApi.subscribe(response => /* Handle response */);
// A third place in your code
getFromWebApi.subscribe(response => /* Handle response */);
// A fourth place in your code
getFromWebApi.subscribe(response => /* Handle response */);
// A fifth place in your code
getFromWebApi.subscribe(response => /* Handle response */);
在五个不同的位置执行此操作将创建五个可观察到的对象,每过10秒就会分别调用一个Web API。如果您每10秒只打一次电话,并且所有订阅都共享响应,这会更好吗?那就是分享让您完成的事情:
let getFromWebApi = interval(10 * 1000).pipe(
mergeMap(_ => callWebApi()),
share()
)
// Somewhere in your code
getFromWebApi.subscribe(response => /* Handle response */);
// ^^^ This will create the observable and start making web requests
// every 10 seconds
// The ones below will not create new observables,
// but receive the same observable as above. They will all receive
// responses every 10 seconds when the original observable returns.
// Somewhere else in your code
getFromWebApi.subscribe(response => /* Handle response */);
// A third place in your code
getFromWebApi.subscribe(response => /* Handle response */);
// A fourth place in your code
getFromWebApi.subscribe(response => /* Handle response */);
// A fifth place in your code
getFromWebApi.subscribe(response => /* Handle response */);
如果您查看此JSBin,您会发现订阅source
五次,创建了五个“请求”。订阅sharedSource
仅创建一个“请求”,