我遇到一些可观察的东西时遇到了麻烦。我似乎无法得到两个 可观察到放在一起很好。他们自己工作得很好,但我 需要两个值。
db.glass.subscribe( ( glass: GlassData[] ): void => {
console.log( glass ); // This prints
});
db.cassette_designs.subscribe( ( cassettes: CassetteData[] ): void => {
console.log( cassettes ): // This prints
});
对于可观察者并不熟悉,我尝试的第一件事就是 将一个嵌套在另一个内部,但内部似乎没有做任何事情。
db.glass.subscribe( ( glass: GlassData[] ): void => {
console.log( glass ); // This prints
db.cassette_designs.subscribe( ( cassettes: CassetteData[] ): void => {
console.log( cassettes ): // This doesn't
});
});
这似乎有点傻,所以我在Google上搜索是否有
更好的方法来结合可观察量,事实证明有一些。我试过了
zip
和forkJoin
,因为它们看起来最像我想做的事,但是
也没有什么能与他们合作。
Observable.zip( db.cassette_designs, db.glass, ( cassettes: CassetteData[], glass: GlassData[] ): void => {
console.log( cassettes ); // doesn't print
console.log( glass ); // doesn't print
});
Observable.forkJoin( [ db.cassette_designs, db.glass ] ).subscribe( ( data: any ): void => {
console.log( data ); // doesn't print
});
这可能是一件简单的事情,因为我没有正确地调用函数,但是
我原本以为我会在某些时候得到某种警告或错误。 tsc
代码没有任何问题,我在开发人员中没有收到任何消息
Chrome或Firefox上的控制台。
我尝试了combineLatest
,但它仍然没有在控制台中显示任何内容。我一定错过了什么,但我不确定是什么。他们个人工作。
Observable.combineLatest( db.cassette_designs, db.glass, ( cassettes: CassetteData[], glass: GlassData[] ): void => {
console.log( cassettes ); // doesn't print
console.log( glass ); // deson't print
});
可观察量以下列方式创建:
...
public Listen( event: string ): Observable<Response>
{
return new Observable<Response>( ( subscriber: Subscriber<Response> ): Subscription => {
const listen_func = ( res: Response ): void => subscriber.next( res );
this._socket.on( event, listen_func );
return new Subscription( (): void =>
this._socket.removeListener( event, listen_func ) );
});
}
...
然后,为了实际获得可观察量,我发送了一个关于相关事件的回复。 e.g。
...
public cassette_designs: Observable<CassetteData[]>;
...
this.cassette_designs = _socket.Listen( "get_cassette_designs" )
.map( ( res: Response ) => res.data.data );
答案 0 :(得分:9)
通过实际订阅结果,我设法让combineLatest
工作
观察到。
最初我这样做了:
Observable.combineLatest( db.cassette_designs, db.glass, ( cassettes: CassetteData[], glass: GlassData[] ): void => {
console.log( cassettes );
console.log( glass );
});
现在我正在这样做:
Observable.combineLatest( db.cassette_designs, db.glass ).subscribe( ( data: any[] ): void => {
console.log( data );
// cassettes - data[0]
// glass - data[1]
});
答案 1 :(得分:6)
跟进你的发现:
1)Observable
是一种惰性执行数据类型,这意味着它在订阅之前不会执行管道中的任何内容。这也适用于组合运算符。 zip
,forkJoin
,combineLatest
和withLatestFrom
都将以递归方式订阅仅在之后传递的Observables
有订阅。
因此:
var output = Observable.combinelatest(stream1, stream2, (x, y) => ({x, y}));
在致电output.subscribe()
之前,实际上不会做任何事情,此时subscribe
和stream1
上也会调用stream2
,您将获得Rx的所有魔力。
2)更小的一点,但每当你开始做自己的创作方法时,首先看一下文档,看看它是否已经存在。有静态创建方法,Arrays
,Promises
,节点式回调,甚至标准event patterns。
因此,您的Listen
方法可以变为:
public Listen<R>(event: string): Observable<R> {
return Observable.fromEvent(this._socket, event);
}
答案 2 :(得分:1)
如果你想要一个发出2个来源的组合数据的单一流(可观察),请查看combineLatest
方法。
答案 3 :(得分:1)
他们两个:Observable.zip和Observable.forkJoin必须工作。 (就个人而言,我更喜欢&#39; forkJoin&#39; - 它会返回一个具有相同顺序的数组,因为你推动了observable,并且你不需要大量的参数)
也许,如果你手动创建observable(Observable.create ......),你就忘了打电话完成&#39;对于两个提供的观察者来说,创造&#39;方法
答案 4 :(得分:0)
我使用了 combineLatest 。我需要三个 API 调用,但我只想要一个对象组合三个响应。
我遵循了同一篇文章中提到的公式:
var output = Observable.combinelatest(stream1, stream2, (x, y) => ({x, y}));
成为最终代码:
getGobalStats(): Observable<any> {
let obs1 = this._http.get(this._config.getGlobalStatsUrl(), this._config.getOptions())
.map((res: Response) => {
return res.json().content;
})
.catch((error: any) => { console.error(error); return error; });
let obs2 = this._http.get(this._config.getGlobalStatsUrl() + '?type=1', this._config.getOptions())
.map((res: Response) => {
return res.json().content;
})
.catch((error: any) => { console.error(error); return error; });
let obs3 = this._http.get(this._config.getGlobalStatsUrl() + '?type=3', this._config.getOptions())
.map((res: Response) => {
return res.json().content;
})
.catch((error: any) => { console.error(error); return error; });
return Observable.combineLatest(obs1,obs2,obs3,(res1,res2,res3) => { return {all:res1,running: res2, cycling: res3}});
}
答案 5 :(得分:0)
Observable.merge(
Observable.fromEvent(canvasEl, 'mousedown'), Observable.fromEvent(canvasEl, 'touchstart'))
.switchMap((e) => {
return Observable.merge(
Observable.fromEvent(canvasEl, 'mousemove').takeUntil(Observable.fromEvent(canvasEl, 'mouseup')),
Observable.fromEvent(canvasEl, 'touchmove').takeUntil(Observable.fromEvent(canvasEl, 'touchend')),
)
.pairwise()
})
.subscribe(...