如何级联RxJs调用以从此人为服务中检索数据。
首先请求转至/ customer / 1
/客户/:ID
响应:
{
Name: "Tom",
Invoices: [1,3],
Orders: [5,6]
}
在客户响应中,我们使用2个InvoiceIds来访问第二个服务:
/发票/:ID
响应
{
Id: 1,
Amount: 10
}
在客户响应中,我们使用2个OrderId来访问第三个服务:
/命令/:ID
响应
{
Id:2,
Date: '2016-11-12'
}
最后,我想用一个看起来像这样的物体:
{
Name: "Tom",
Invoices: [
{
Id: 1,
Amount: 10
},
{
Id: 3,
Amount: 5
}],
Orders: [
{
Id:5,
Date: '2016-11-12'
},
{
Id:6,
Date: '2016-11-12'
}]
}
如何通过管道传递id,以便检索相关对象。
我的直觉告诉我,我应该使用flatMap运算符,但我完全不确定这一切是如何协同工作的。
var ajax = Rx.DOM.getJSON('/api/customers/1')
.flatMap(p => p.Invoices.map(x =>
Rx.DOM.getJSON('/api/invoices/' + x)
));
答案 0 :(得分:2)
这是一个典型的用例,您需要在几个HTTP调用中构造响应:
const Observable = Rx.Observable;
var customerObs = Observable.create(observer => {
Observable.of({Name: "Tom", Invoices: [1,3], Orders: [5,6]})
.subscribe(response => {
var result = {
Name: response.Name,
Invoices: [],
Orders: [],
};
let invoicesObs = Observable.from(response.Invoices)
.flatMap(id => Observable.of({ Id: Math.round(Math.random() * 50), Amount: Math.round(Math.random() * 500) }).delay(500))
.toArray();
let ordersObs = Observable.from(response.Orders)
.flatMap(id => Observable.of({ Id: Math.round(Math.random() * 50), Amount: Math.round(Math.random() * 500) }).delay(400))
.toArray();
Observable.forkJoin(invoicesObs, ordersObs).subscribe(responses => {
result.Invoices = responses[0];
result.Orders = responses[1];
observer.next(result);
});
});
});
customerObs.subscribe(customer => console.log(customer));
查看现场演示:https://jsfiddle.net/martinsikora/uc1246cx/
我正在使用Observable.of()
模拟HTTP请求,flatMap()
将每个发票/订单ID转换为重新发送的Observable(另一个HTTP请求),然后toArray()
收集所有从运算符链发出的值,并将它们重新发送到一个数组中(只是因为它很方便)。
运算符forkJoin()
等待所有源Observable完成,然后将它们的最后一个值作为数组发出(所以我们在responses
中发现了数组数组。)