Javascript Rxjs-在缓存为空时使用API输出并重新查询

Javascript Rxjs-在缓存为空时使用API输出并重新查询,javascript,rxjs,reactive-programming,Javascript,Rxjs,Reactive Programming,我正在尝试实现()的一个版本,它不是从返回的API数组中拾取一个随机对象,而是从返回的API数组中消耗一个反向限制的对象流 下面是代码的一部分,它从API响应(full fiddle)生成受控的可观察的: 我只需在控制台中转储每个发出的用户。log,并使用单击事件流来触发受控可观察对象中的请求()调用: responseStream.subscribe(function(user) { console.log(user); }); refreshClickStream.subscribe(

我正在尝试实现()的一个版本,它不是从返回的API数组中拾取一个随机对象,而是从返回的API数组中消耗一个反向限制的对象流

下面是代码的一部分,它从API响应(full fiddle)生成受控的
可观察的

我只需在
控制台中转储每个发出的用户。log
,并使用
单击事件流来触发受控可观察对象中的
请求()
调用:

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

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

从GitHub API返回了大约50个用户对象,我希望每次单击都使用一个(如上所示)。但是,在我刚用完用户对象之后,我想向
requestStream
发送另一个调用,以获取另一个API调用,补充
responseStream
,并在每次单击时继续向
控制台提供用户对象。RxJS友好的方法是什么?

我会用
CombineTest()
类似于文章示例,尽管我想知道是否有比我更简单的方法

我只要求3件东西。使用3项是硬编码的,因此您需要修改此项。我正在考虑使它通用化,但这需要使用
主题
,并且使它更加复杂,所以我继续使用这个简单的示例

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

见现场演示:

我使用
refreshClickStream
两次:

  • CombineTest()中发出数组中的下一项
  • 要检查这是否是数组的结尾,我们需要发出另一个请求(即
    filter()
    操作符)
因为当您单击
索引%3==0
时,时间实际上会触发两次发射,所以最后是必需的。第一个是从下载数据得到的,第二个是直接在
combinelateest()
中,我们希望忽略它,因为我们不想再次迭代相同的数据。由于
distinct()
,它被忽略,只传递新值


我试图在不使用
distinct()
的情况下找到一个方法,但我找不到任何方法。

哇,这太聪明了。我在想,如果不使用
Subject
s,就不会有解决方案,但你做到了!在某种程度上,我们正在流中构建数组迭代器并重置它。那很酷。您提到必须使用
Subject
s使其具有通用性-这是因为我们必须在数组中期待向主题发送
onNext
,并触发另一个API拉取吗?@MaxAlcala我想使用
Subject
将其输入
过滤器()
在知道数组中有多少项之前必须使用它。
responseStream.subscribe(function(user) {
  console.log(user);
});

refreshClickStream.subscribe(function (res) {
    responseStream.request(1);
});
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);
});