[英]Reactive javascript - convert ajax calls to Bacon.js stream with pagination
How can I convert calls to server API, with pagination support, to a Bacon.js / RxJs stream? 如何通过分页支持将对服务器API的调用转换为Bacon.js / RxJs流?
For the pagination I want to be able to store the last requested item-index, and ask for the next page_size items from that index to fill the stream. 对于分页,我希望能够存储上次请求的item-index,并从该索引中请求下一个page_size项以填充流。
But I need the 'load next page_size items' method to be called only when all items in stream already been read. 但是我只需要在流中的所有项目都已被读取时才调用“ load next page_size items”方法。
Here is a test that I wrote: 这是我编写的测试:
var PAGE_SIZE = 20;
var LAST_ITEM = 100;
var FIRST_ITEM = 0;
function getItemsFromServer(fromIndex) {
if (fromIndex > LAST_ITEM) {
return [];
}
var remainingItemsCount = LAST_ITEM-fromIndex;
if (remainingItemsCount <= PAGE_SIZE) {
return _.range(fromIndex, fromIndex + remainingItemsCount);
}
return _.range(fromIndex, fromIndex + PAGE_SIZE);
}
function makeStream() {
return Bacon.fromBinder(function(sink) {
var fromIndex = FIRST_ITEM;
function loadMoreItems() {
var items = getItemsFromServer(fromIndex);
fromIndex = fromIndex + items.length;
return items;
}
var hasMoreItems = true;
while (hasMoreItems) {
var items = loadMoreItems();
if (items.length < PAGE_SIZE) { hasMoreItems = false; }
_.forEach(items, function(item) { sink(new Bacon.Next(item)); });
}
return function() { console.log('done'); };
});
}
makeStream().onValue(function(value) {
$("#events").append($("<li>").text(value))
});
http://jsfiddle.net/Lc2oua5x/10/ http://jsfiddle.net/Lc2oua5x/10/
Currently the 'getItemsFromServer' method is only a dummy and generate items locally. 当前,“ getItemsFromServer”方法只是一个虚拟对象,可在本地生成项目。 How to combine it with ajax call or a promise that return array of items? 如何将其与ajax调用或返回项目数组的promise结合使用? and can be execute unknown number of times (depends on the number of items on the server and the page size). 并且可以执行未知次数(取决于服务器上的项目数和页面大小)。
I read the documentation regarding Bacon.fromPromise() but couldn't manage to use it along with the pagination. 我阅读了有关Bacon.fromPromise()的文档,但无法与分页一起使用。
You need to use flatMap
to map pages to streams created with Bacon.fromPromise
. 您需要使用flatMap
将页面映射到使用Bacon.fromPromise
创建的流。 Here is a working example, where I use the jsfiddle echo endpoint ( it sends the same data back ) 这是一个工作示例,其中我使用jsfiddle echo端点(它将相同的数据发送回)
Bacon.sequentially(0, _.range(0,5))
.map(toIndex)
.flatMap(loadFromServer)
.onValue(render)
function toIndex(page) {
return page * PAGE_SIZE
}
function loadFromServer(index) {
var response = getItemsFromServer(index)
return Bacon.fromPromise($.ajax({
type: 'POST',
dataType: 'json',
url: '/echo/json/',
data : { json: JSON.stringify( response ) }
}))
}
function render(items) {
items.forEach(function(item) {
$("#events").append($("<li>").text(item))
})
}
http://jsfiddle.net/1eqec9g3/2/ http://jsfiddle.net/1eqec9g3/2/
Note: this code relies on responses coming from the server in the same order they were sent. 注意:此代码依赖于来自服务器的响应(发送顺序相同)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.