2016-09-19 39 views
2

我有数据类角2个+ rxjs - 与几个后续HTTP提取对象的返回流如何请求

class Processor { 
    frequency: number; 
    error: booelan; 
} 

class Computer { 
    name: string; 
    processor: Processor[]; 
} 

我使用JSON faetch它从后端:

{ 
    "name": "Alfa Beta", 
    "processors": [ 
     { 
      "url": "ASD3-455R-FRTT-ASEW" 
     }, 
     { 
      "url": "AQW2-DFFFR-367K-MMKE" 
     } 
    ] 
} 

和单个处理器

{ 
    "url": "ASD3-455R-FRTT-ASEW", 
    "frequency": 2200, 
    working: true 
} 

我需要返回流Computer,因为我想问问处理器st atus每分钟。对于单个返回的实例Computer,我需要发送3个相互依赖的http请求。当然,我会为此使用服务类。对我来说唯一的麻烦是如何创建这个流,即。 this.http.get(this.mainUrl)

我找到了Reactive programming, HTTP and Angular 2和章节执行一个请求,结果是前一个但它没有帮助。

回答

2

这看起来像concatMap operator工作(顺便说一句,我有一个非常类似的问题前段时间How to use exhaustMap in ReactiveX/rxjs 5 in TypeScript)。

比如为了运行几个请求:

import { Observable } from 'rxjs/Observable'; 
import 'rxjs/add/operator/concatMap'; 
import 'rxjs/add/operator/do'; 

var urls = [ 
    'https://httpbin.org/get?1', 
    'https://httpbin.org/get?2', 
    'https://httpbin.org/get?3', 
    'https://httpbin.org/get?4', 
    'https://httpbin.org/get?5', 
];  

Observable.from(this.urls) 
    .concatMap(url => http.get(url)) 
    .subscribe(response => console.log(response.url)) 
; 

此打印到控制台:

https://httpbin.org/get?1 
https://httpbin.org/get?2 
https://httpbin.org/get?3 
https://httpbin.org/get?4 
https://httpbin.org/get?5 

concatMap()每个值(在我们的情况下,每个URL)映射到一个Observable和再发射所有的值直到完成。然后继续从可调用函数返回的下一个Observable。我们知道http.get()返回的Observable仅与Response对象发出一个值,然后完成。

见plnkr演示:http://plnkr.co/edit/PJ7SpkNgBjZz2h4uvRpK?p=preview(在app.component.ts

你说的要求是互相依赖的(一个请求是依赖于前一个请求的结果?),所以也许更好的解决方案可能是以下几点:

http.get('https://httpbin.org/get?1') 
    .do(response => console.log('Process response', response.url)) 

    .concatMap(response => { 
    console.log('Previous response', response.url, ' about to run /get?2') 
    return http.get('https://httpbin.org/get?2') 
    }) 
    .do(response => console.log('Process response', response.url)) 

    .concatMap(response => { 
    console.log('Previous response', response.url, ' about to run /get?3') 
    return http.get('https://httpbin.org/get?3') 
    }) 

    .subscribe(response => console.log('Done', response.url)) 
; 

输出控制台:

Process response https://httpbin.org/get?1 
Previous response https://httpbin.org/get?1 about to run /get?2 
Process response https://httpbin.org/get?2 
Previous response https://httpbin.org/get?2 about to run /get?3 
Done https://httpbin.org/get?3 

同样,我们使用concatMap()把每个值到Observable,但是这次我们使用它来保证正确的顺序并能够访问前面的http.get()调用的结果。我还使用do() operator来分离逻辑,该逻辑处理来自逻辑的先前响应,该逻辑创建下一个更好可读性的请求(尽管这可能全部进入concatMap())。 (在app.component.ts