Observable继续调用API并根据条件更改参数

时间:2016-09-30 18:18:33

标签: angular typescript rxjs rxjs5

我已阅读Rx.js repeat文档,试图了解如何根据我从API收到的回复来继续调用api。我拨打的API只能一次发回2k条记录。 API将发回一个值以便我发送它,以便我可以继续接收记录,直到它们返回完成值。

所以流程如下:

  1. GET请求提供查询参数reqMode=''
  2. 使用包含reqModevalue的最后一个数组检索回复。
  3. 如果我收到done,那么我需要发出相同的请求,但会发送带有值的value参数。
  4. 如果我收到reqMode,那么我将停止并返回自第一次通话以来的所有记录。
  5. 我在done时获得了第一组值,但这是我在阅读文档后的尝试,但它没有意义:

    subscribing normally

    尝试使用类型为getRecords(){ let url = this.url + 'reqMode='; return this.http.get(url) .doWhile() //What would I do here } 的Observable执行.doWhile时。我正在寻找使用Observables的任何替代方案来完成我需要做的事情。

2 个答案:

答案 0 :(得分:6)

我不认为repeat()是一个很好的运营商。如果我理解正确,您希望根据先前请求的响应重复HTTP请求。如果您想多次重复相同的请求,则运营商repeat()会很好。

我使用concatMap()并递归调用自己,直到reqMode"done"为止:

查看现场演示:http://plnkr.co/edit/w0DdepslTaKrLSB3aIkA

import {Observable, Subject} from 'rxjs';

const result = new Subject();
const closeBuffer = new Subject();
const buffer = result.buffer(closeBuffer.asObservable());

function sendHttpRequest(reqMode) {
  return Observable.of('{"reqMode":' + reqMode + '}')
    .map(response => JSON.parse(response))
    .concatMap(data => {
      console.log('HTTP Response:', data);
      // Add data to the buffer of results
      result.next(data);

      if (data.reqMode == 'done') {
        // Return an empty value wrapped as an Observable so concatMap can work
        // with it and emit onNext when it completes (which is immediately
        // thanks to the `.of()` operator).
        return Observable.of(null);
      } else {
        // Simulate that the next call returns 'done'
        return sendHttpRequest('"done"');

        // Uncomment this for real usage
        //return sendHttpRequest(data.reqMode);
      }
    });
}

// Subscribe to the buffer where I'll receive the value.
buffer.subscribe(val => console.log('Next: ', val));

// Simulate HTTP request with reqMode = 42
sendHttpRequest(42).subscribe(() => {
  console.log('done');
  // Emit values from the buffer.
  closeBuffer.next(null);
  closeBuffer.complete();
});

我使用of()运算符来模拟请求并返回包含为Observable的值。我还使用Subject来保存使用buffer()运算符缓冲的所有响应。我订阅缓冲区以获取最终的响应数组(如果将此代码包装到函数中,您很可能会返回buffer以后可以订阅的地方。)

回应如下:

HTTP Response: Object {reqMode: 42}
HTTP Response: Object {reqMode: "done"}
Next:  [Object, Object]

查看类似问题:Angular 2 + rxjs - how return stream of objects fetched with several subsequent http requests

答案 1 :(得分:3)

所以我通过使用包裹observer和使用.repeat()来举例说明如何做到这一点。

所有逻辑都在app.component.ts

Checkout this plunker

我在代码中留下了注释,但实际上它会发出一个http请求,它会增加一个计数,然后会发出另一个具有不同查询号的请求。它将重复,直到达到5。

你必须修改它,以便"重复条件"代表你的逻辑。

希望有所帮助!