Rxjs - 使用API​​输出并在缓存为空时重新查询 [英] Rxjs - Consume API output and re-query when cache is empty

查看:91
本文介绍了Rxjs - 使用API​​输出并在缓存为空时重新查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实施此简介的版本RxJS 在这里捏捏)而不是从返回的API中选择一个随机对象在数组中,它使用返回的API数组中的反向流入的对象流。

I'm trying to implement a version of this intro to RxJS (fiddle here) that instead of picking a random object from a returned API array, it consumes a backthrottled stream of objects from the returned API array.

这是从API响应产生受控 Observable 的代码的一部分(完全小提琴这里):

Here's a portion of the code that produces a controlled Observable from the API response (full 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 ,并使用单击事件流来触发受控Observable中的 request()调用:

I just dump each emitted user in console.log, and use a click event stream to trigger the request() call in the controlled Observable:

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

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

GitHub API返回了大约50个用户对象,我想反向消耗它们每次点击一次(如上所示)。 然而,在我刚刚用完用户对象之后,我想发送另一个调用 requestStream 来获取另一个API调用,补充 responseStream 并在每次点击时继续向 console.log 提供用户对象。什么是RxJS友好的方式呢?

There's about 50 user objects returned from the GitHub API, and I'd like to backthrottle-consume them one per click (as seen above). However, after I'm fresh out of user objects I'd like to send in another call to requestStream to fetch another API call, replenish the responseStream and continue providing user objects to console.log upon each click. What would be the RxJS-friendly way to do so?

推荐答案

我的做法类似于文章示例 combineLatest()虽然我想知道是否有比我更简单的方法。

I'd do it similarly to the article example with combineLatest() although I wonder if there's an easier way than mine.

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

I'm making request for only 3 items. Working with 3 items is hardcoded so you'll want to modify this. I was thinking about making it universal but that would require using Subject and made it much more complicated so I stayed with this simple example.

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

Also, I'm using concatMap() to trigger fetching more data. However, just clicking the link triggers just the combineLatest() which emits another item from the array.

查看直播演示: 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()运算符)。

  • to emit next item in the array in combineLatest()
  • to check whether this is the end of the array and we need to make another request (that's the filter() operator).

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

At the end distinct() is required because when you click index % 3 === 0 time triggers in fact two emission. First is the one from downloading the data and the second one is directly in combineLatest() that we want to ignore because we don't want to iterate the same data again. Thanks to distinct() it's ignored and only the new values is passed.

我试图找出一个方法没有使用 distinct()但我找不到任何方法。

I was trying to figure out a method without using distinct() but I couldn't find any.

这篇关于Rxjs - 使用API​​输出并在缓存为空时重新查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆