用RxJs级联ajax调用

时间:2016-11-02 08:23:27

标签: javascript rxjs

如何级联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)
        ));

1 个答案:

答案 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中发现了数组数组。)

查看类似的问题:Performing advanced http requests in rxjs