我读过article,其中显示了对HTTP请求进行3次异步订阅的示例。
@Component({
selector: 'my-app',
template: `
<div>
<p>{{ (person | async)?.id }}</p>
<p>{{ (person | async)?.title }}</p>
<p>{{ (person | async)?.body }}</p>
</div>
`,
})
export class App {
constructor(public http: Http) {
this.person = this.http.get('https://jsonplaceholder.typicode.com/posts/1')
.map(res => res.json())
}
}
我已经知道这里不需要异步,并且可以使用ReplaySubject并且还有许多其他解决方案,但这不是我想要的。
作者说:
人们建议的当前解决方案:
this.http.get('https://jsonplaceholder.typicode.com/posts/1') .map(res => res.json()).share()
(publish().refCount().
)
问题:
但重新考虑publish().refCount()
- 是否有可能(出于某种原因):
第一个(person | async)
已经执行了请求(refcount = 1)并且响应在<!>之前返回最后两个(person | async)
订阅了? - 这会导致另一个http请求?我的意思是 - 谁保证3个订阅将同时可用以便它们共享相同的结果?竞争条件有可能吗? 因为我听说refcount()受竞争条件限制。
此外,什么时候被认为是“refcount()>0
”?当http 被调用时检查该值,还是在响应到达时检查它?
换句话说 -
sub1
导致refcount()=1
(调用http)。但同时sub2
(第二次订阅):
sub1 ———————A—————> http invoked
<—————————B———————response
关注A
&amp; B
阶段:
refcount()
何时2
?它是在舞台A
上(在执行http之前/期间)还是在B
阶段订阅也会被视为refcount()=2
?
答案 0 :(得分:1)
这确实是一个有趣的问题。但我认为这段代码中没有竞争条件。
问题是,所有订阅都在{{1>}功能的模板中以同步完成。
这意味着,当第一次订阅确实完成时,将触发请求,但是如果服务器在所有其他订阅完成之前响应(如果甚至可能),那么主线程将被占用因此不会触发另一个请求当下一个async
到达时。
这是我尝试重现该用例的一个小例子。
subscribe
&#13;
const timer = Rx.Observable.of("value")
.do(() => console.log("start request"))
.delay(1)
.do(() => console.log("end request"))
.publish().refCount()
console.time("sub");
for (var i=0; i < 10; i++) {
console.log("subscribe" + i)
timer.subscribe()
}
console.timeEnd("sub")
&#13;
这里我模拟服务器在<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>
中响应的请求,但所有订阅(至少在我的计算机上)都在1ms
左右完成。所以你可以说在订阅完成之前响应就到了。
正如您在日志中看到的那样,请求只被触发一次:)