Angular2 2.0.0-beta.15,Rxjs 5.0.0-beta.2
我有两个简单的rxjs observable,一个是共享的,一个不是(.share()调用它)
我有一个angular2组件,它订阅两个observable并在其模板中显示值,该模板也使用异步管道订阅了observable.
我单击一个按钮,在两个带有一些垃圾的observable上设置.next().
模板更新并显示每个模板的最新值.组件中的订阅功能不会为非共享的observable触发.为什么?
plunkr:https://plnkr.co/edit/IIWvnTT1zLit1eUNknkk ? p = preview
@Component({
selector: 'my-app',
template: `
<div>
<div>obs1 value: {{ observable1 | async }}</div>
<div>obs2 value: {{ observable2 | async }}</div>
<button (click)="randomizeIt()">randomize it</button>
<br>
<h3>Question 1</h3>
Why is obs1's initial value (from startWith) not displayed?
<h3>Question 2</h3>
Why does our subscription to obs2 never fire on new values?<br>
check console.log to see what i mean.
</div>`,
})
export class App {
public observable1:Observable<string>;
public observer1:any;
public observable2:Observable<string>;
public observer2:any;
constructor() {
this.observable1 = Observable.create(observer => {
this.observer1 = observer;
}).startWith("initial obs 1 value").share();
this.observable1.subscribe((val) => {
console.log('YOU WILL SEE THIS:', val);
})
this.observable2 = Observable.create(observer => {
this.observer2 = observer;
}).startWith("initial obs 2 value"); // no share!
this.observable2.subscribe((val) => {
console.log('WHY DOES THIS NEVER FIRE ON NEW VALUES?:', val);
})
}
public randomizeIt() {
let r = Math.random();
console.log('set both obs to: ', r);
this.observer1.next(r);
this.observer2.next(r);
}
}
Run Code Online (Sandbox Code Playgroud)
提前致谢!
Q1.为什么没有显示obs1的初始值(来自startWith)?
来自share()文档:
返回一个可观察序列,该序列共享对基础序列的单个订阅.
这意味着,在您的情况下,{{ observable1 | async }}并且this.observable1.subscribe(....)共享相同的订阅,并且当您observable1在构造函数中订阅时,您已经启动了序列.初始化视图时,observable1已经开始订阅并发出第一个值.所以async会调用subscribe(),但不会得到序列的第一个发射.
因此,如果您将订阅移至内部ngAfterViewInit(),则初始值将转至async订阅.
ngAfterViewInit(){
this.observable1.subscribe((val) => {
console.log('YOU WILL SEE THIS CHANGE:', val);
})
}
Run Code Online (Sandbox Code Playgroud)
Q2.为什么我们对obs2的订阅从未触发新值?
每次订阅冷 Observable时,实际上都会创建一个新的Observable实例.创建新实例时,还会创建一个新的观察者实例.因此,您对构造函数的订阅是可观察的instance1和观察者的instance1,订阅依次async是可观察instance2和观察者instance2.所以,当你打电话时randomizeIt(),你调用的observer2是instance2哪个被观察者instance2订阅了async.
让你的观察"热":
let obs = Observable.create(observer => {
this.observer2 = observer;
}).startWith("initial obs 2 value");
this.observable2 = obs.publish();
this.observable2.subscribe((val) => {
console.log('WHY DOES THIS NEVER FIRE?:', val);
})
this.observable2.connect();
Run Code Online (Sandbox Code Playgroud)
更新
让我们假设您有一个发出随机值的observable:
this.observable3 = Observable.create(observer => {
observer.next(Math.random());
});
Run Code Online (Sandbox Code Playgroud)
现在,每次订阅this.observable3您都会获得一个新的随机值.每个订户的价值不同.因为每个订户都有一个新实例.
来自文档:
将寒冷和热的Observable视为可以观看的电影或表演("订阅")会有所帮助.
冷观察:电影.
热门观察:现场表演.
热门观察者重播:录制在视频上的现场表演.每当你看电影时,即使所有电影观察者都看到相同的效果,你的电影也会独立于其他任何人的电影.另一方面,多个观看者共享现场表演.如果你迟到现场表演,你会错过一些.但是,如果它是在视频上录制的(在RxJS中,这将发生在BehaviorSubject或ReplaySubject上),您可以观看现场表演的"电影"..publish().refCount()现场表演是艺术家在没有人观看时退出比赛,并且当观众中至少有一个人时再次开始播放.
| 归档时间: |
|
| 查看次数: |
4628 次 |
| 最近记录: |