我正在尝试实现 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/