我有数据类
class Processor {
frequency: number;
error: booelan;
}
class Computer {
name: string;
processor: Processor[];
}
我使用 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)
?
我找到了 Reactive programming, HTTP and Angular 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
Operator 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()
)。
参见 plnkr 演示:http://plnkr.co/edit/VFv09dTekK8av1Pu3a75?p=preview (在app.component.ts
中)
关于Angular 2 + rxjs - 如何返回通过多个后续 http 请求获取的对象流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39566268/