Angular 2 + rxjs-如何返回通过多个后续HTTP请求获取的对象流 [英] Angular 2 + rxjs - how return stream of objects fetched with several subsequent http requests

查看:119
本文介绍了Angular 2 + rxjs-如何返回通过多个后续HTTP请求获取的对象流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有数据类

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

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

我使用json从后端获取它:

I faetch it from backend using json:

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

和单处理器

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

我需要返回Computer的流,因为我想每分钟询问处理器状态.对于Computer的单个返回实例,我需要发送3个彼此依赖的http请求.当然,我将为此使用服务类.我唯一的麻烦是如何创建此流,即. this.http.get(this.mainUrl)?

I need to return stream of Computer as I'd like to ask for processors status each minute. For single returned instance of Computer I need to send 3 http requests with dependencies on each other. Of course I'll use service class for this. The only trouble for me is how to create this stream, ie. this.http.get(this.mainUrl)?

我发现反应式编程,HTTP和Angular 2 一章以上一个请求的结果执行请求,但这没有帮助.

I've found Reactive programming, HTTP and Angular 2 and chapter Executing a request with the result of a previous one but it didn't help.

推荐答案

这似乎是).

例如按顺序运行多个请求:

For example running several request in order:

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()返回的ObservableResponse对象仅发出一个值,然后完成.

Operator concatMap() maps each value (each URL in our case) into an Observable and re-emits all its values until it's complete. Then it carries on with the next Observable returned from the callable. We know that http.get() returns an Observable that emits just one value with the Response object and then completes.

请参阅plnkr演示: http://plnkr.co/edit/PJ7SpkNgBjZz2h4uvRpK?p=预览(在app.component.ts中)

See plnkr demo: http://plnkr.co/edit/PJ7SpkNgBjZz2h4uvRpK?p=preview (in app.component.ts)

您说请求彼此依赖(一个请求取决于上一个请求的结果吗?),所以也许有以下更好的解决方案:

You said the request depend on each other (one request is dependent on the result of the previous request?) so maybe a better solution could be the following:

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()运算符仅将处理上一个响应的逻辑与创建下一个请求以提高可读性的逻辑分开(即使这可以全部放入concatMap()中).

Again, we're using concatMap() to turn each value into an Observable but this time we're using it to only guarantee the correct order and to be able to access the result from the previous http.get() call. I also used do() operator only to separate logic that processes the previous response from logic that creates the next request for better readability (even though this could all go into concatMap()).

请参阅plnkr演示: http://plnkr.co/edit/VFv09dTekK8av1Pu3a75?p=preview (在app.component.ts中)

See plnkr demo: http://plnkr.co/edit/VFv09dTekK8av1Pu3a75?p=preview (in app.component.ts)

这篇关于Angular 2 + rxjs-如何返回通过多个后续HTTP请求获取的对象流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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