javascript - Rxjs - 当缓存为空时消费 API 输出并重新查询

标签 javascript rxjs reactive-programming

我正在尝试实现 this intro to RxJS 的一个版本( fiddle here ) 它不是从返回的 API 数组中选择随机对象,而是使用返回的 API 数组中的对象流。

这是从 API 响应中生成受控 Observable 的部分代码(完整的 fiddle here ):

var responseStream = requestStream.flatMap(function (requestUrl) {
    return Rx.Observable.fromPromise(fetch(requestUrl));
}).flatMap(function(response) {
    return Rx.Observable.fromPromise(response.json());
}).flatMap(function(json) {
    return Rx.Observable.from(json);
}).controlled();

我只是将每个发出的用户转储到 console.log 中,并使用 click 事件流来触发 request() 调用受控的可观察对象:

responseStream.subscribe(function(user) {
  console.log(user);
});

refreshClickStream.subscribe(function (res) {
    responseStream.request(1);
});

从 GitHub API 返回了大约 50 个用户对象,我想在每次点击时反向使用它们一个(如上所示)。 但是,在我从用户对象中恢复过来后,我想发送另一个对 requestStream 的调用以获取另一个 API 调用,补充 responseStream 并在每次点击时继续向 console.log 提供用户对象。这样做对 RxJS 友好的方式是什么?

最佳答案

我会像使用 combineLatest() 的文章示例那样做,尽管我想知道是否有比我的更简单的方法。

我只请求 3 件商品。使用 3 个项目是硬编码的,因此您需要修改它。我正在考虑让它变得通用,但这需要使用 Subject 并使它变得更加复杂,所以我保留了这个简单的例子。

此外,我正在使用 concatMap() 来触发获取更多数据。但是,只需单击链接即可触发 combineLatest(),它会从数组中发出另一个项目。

查看现场演示:https://jsfiddle.net/h3bwwjaz/12/

var refreshButton = document.querySelector('#main');
var refreshClickStream = Rx.Observable.fromEvent(refreshButton, 'click')
  .startWith(0)
  .scan(function(acc, val, index) {
    return index;
  });

var usersStream = refreshClickStream
  .filter(function(index) {
    return index % 3 === 0;
  })
  .concatMap(function() {
    var randomOffset = Math.floor(Math.random() * 500);
    var url = 'https://api.github.com/users?since=' + randomOffset + '&per_page=3';
    return Rx.Observable.fromPromise(fetch(url))
      .flatMap(function(response) {
        return Rx.Observable.fromPromise(response.json());
      });
  })
  .combineLatest(refreshClickStream, function(responseArray, index) {
    return responseArray[index % 3];
  })
  .distinct();

usersStream.subscribe(function(user) {
  console.log(user);
});

我使用 refreshClickStream 两次:

  • combineLatest()
  • 中发出数组中的下一个项目
  • 检查这是否是数组的末尾,我们需要发出另一个请求(即 filter() 运算符)。

最后distinct()是必需的,因为当您单击 index % 3 === 0 时,实际上会触发两次发射。第一个是来自下载数据的,第二个是直接在 combineLatest() 中,我们想忽略它,因为我们不想再次迭代相同的数据。感谢 distinct() 它被忽略了,只有新值被传递。

我试图找出一种不使用 distinct() 的方法,但我找不到任何方法。

关于javascript - Rxjs - 当缓存为空时消费 API 输出并重新查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40348748/

相关文章:

php - 缺少 : after property list

javascript - 将 html.actionLink 添加到 Jquery 数据表

javascript - 如何创建一个 Observable 并同时将该 Observable 中的值存储到另一个 Observable 中?

Angular2 可观察定时器条件

java - RxJava : How to get all results AND errors from an Observable

scala - 检查可观察对象是否完成的好方法是什么

javascript - websocket 客户端在快速调用 socket.send() 时间歇性无法传输

javascript - 将 ng-include 与 IIS 一起使用

angular - 使用 NgRX 实体规范化 Api 响应

java - Reactor Mono - 执行并行任务