RxJS Observable.concat:如何知道下一个结果来自何处? [英] RxJS Observable.concat: How to know where next result came from?

查看:270
本文介绍了RxJS Observable.concat:如何知道下一个结果来自何处?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序(使用TypeScript编写的具有RxJS 5的Angular 2)要求我以预定义的顺序对Web服务进行两次调用.受此页启发决定尝试使用RxJS observables的 concat 运算符.不同的是,接收值的 onNext 回调需要根据它们来自何处将它们转发给不同的处理程序

My application (Angular 2 with RxJS 5 written in TypeScript) requires me to make 2 calls to a web service in a predefined order. Inspired by this page I decided to try the concat operator of RxJS observables. The twist is that the onNext callback that receives values needs to forward them to different handlers depending on where they came from

我的代码可以简化为:

suscription1 = Observable.return({name:'John', age:7});
subscription2 = Observable.return({name:'Mary', color:'blue'}); 
Observable.concat(subscription1, subscription2).subscribe(
    data=>{ /* need to know which subscripion 
             i'm dealing with to direct to the right handler*/}
);

确定每种可观察到的发射数据来自哪里的最优雅的方法是什么?我想到了几种方法,但它们似乎都很笨拙:

What's the most elegant way to determine where my data came from at each observable emission? I have thought of a couple of ways but they all seem clumsy:

  1. 在范围内保留一个计数器,也许作为一个类属性.对其进行检查并在每次收到结果时对其进行递增.由于每个可观察对象仅发射一次,因此计数器在第一个订阅输出时将具有其初始值,而在第二个订阅输出时将具有initial + 1.问题是,当我不知道每个可观察对象在完成之前会发射多少次时,这将无法工作.

  1. Keep a counter in scope, perhaps as a class property. Check it and increment it each time you receive a result. Since each observable emits just once, the counter will have its initial value when the first subscription outputs and it will have initial+1 when the second outputs. Problem is this won't work when I don't know how many times each observable will emit before being complete.

检查每个结果,并根据结果的形状识别其来源.例如,在我的示例中,只有第一个可观察的结果具有 age 属性.显然,当结果具有相同形状时,这变得不切实际.

Inspect each result and identify its source by the result's shape. For instance, in my example only the first observable's result has an age property. Obviously this becomes impractical when the results have the same shape.

完全摆脱 concat 运算符;在 subscription1 onComplete 处理程序中订阅 subscription2 .这可以工作,但是扩展性不佳.如果我有4个或5个要串联的订阅,它将变成嵌套地狱.

Get rid of the concat operator altogether; subscribe to subscription2 in the onComplete handler of subscription1. This would work, but it doesn't scale well; if I have 4 or 5 subscriptions to concatenate, it becomes nested hell.

只有2个订阅的解决方案3 ...

Solution 3 with just 2 subscriptions...

suscription1 = Observable.return({name:'John', age:7});
subscription2 = Observable.return({name:'Mary', age:8}); 
subscription1.subscribe(
    data=> this.handlerOne(data),
    error=>{},
    ()=> {
        subscription2.subscribe(
            data=>this.handlerTwo(data),
            error=>{},
            ()=>console.log('All subscriptions completed!')
        )
    }
);

所以我的问题是:当使用 Observable.concat 依次订阅多个可观察对象时,我的 onNext 处理程序如何确定数据来自何处?或者,是否应该为此目的使用其他运算符?我不能使用 forkJoin 运算符,因为完成订阅的顺序很重要.

So my question: When using Observable.concat to subscribe to several observables in sequence, how can my onNext handler determine where the data came from? Alternatively, is there another operator I should be using for this purpose? I cannot use the forkJoin operator because the order in which the subscriptions are completed is important.

推荐答案

您可以映射这些订阅以了解其来源.

You could mapthe suscriptions to know where it's coming from.

suscription1 = Observable.return({name:'John', age:7})
         .map(person => { person.source = 1; return person };
subscription2 = Observable.return({name:'Mary', age:8})
         .map(person => { person.source = 2; return person };

然后,您可以轻松确定其来源:

Then you can easily determine where it comes from:

Observable.concat(subscription1, subscription2).subscribe(
    data=> { if (data.source == 1) /* do whatever */ }
);

这篇关于RxJS Observable.concat:如何知道下一个结果来自何处?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆