Stream JSON with RxJS Observable

不羁岁月 提交于 2019-12-22 01:17:01

问题


I'm trying to understand a few things about RxJs. What I would like to do is consume some JSON data and immediately begin to render that data on the DOM as it's coming in. I've setup the stream request, response, and display. It's outputting every just fine but it's doing it all at once and not over time.

I want to start showing the data on the page as its coming in, instead of waiting for the whole file to complete then show at once which would create a long wait time.

//Cache the selector
var $resultList = $('.results');

//Gets the JSON (this will not be a static file,just for testing)
var requestStream = Rx.Observable.just("/results.json");

var responseStream = requestStream
    .flatMap(function(requestUrl) {
            return Rx.Observable.fromPromise(jQuery.getJSON(requestUrl))
             });

var displayStream = responseStream.subscribe(
    function(response) {
    //This maps to a Handlebars Template and puts it on the DOM
    $resultList.html(compiledTemplate(response)); 
            },
            function(err) {
                    console.log('Error: %s', err);
             },
             function() {
                    console.log('Completed');
             });




//Sample of the data from the JSON file
Object{
    beginIndex: "1"
    catId: "111"
    endIndex: "1"
    products: Array[100]

}

回答1:


If I understand well, there are two relevant points to make:

  1. you need to find a way to have a stream of objects from that file instead of one big object when you finish reading that file (I want to start showing the data on the page as its coming in). The mechanics of that would depend first on the structure of the source (file and file reading mechanism) than on Rxjs (is every line an object that can lead to information display etc.?). Once you have that 'minimum displayable unit of information' you can use Rxjs to buffer/process it if need be (do you want to display something for each object, or each 100 objects, or remove uncessary attributes etc.?)
  2. you need to update your display incrementally as new data arrive. That means you need something like $resultList.html($resultList.html() + compiledTemplate(response)); to append the new compiled html to the old one.

UPDATE : for chunking an array, you can have a look at this jsfiddle : http://jsfiddle.net/429vw0za/

var ta_result = document.getElementById('ta_result');

function emits ( who, who_ ) {return function ( x ) {
 who.innerHTML = [who.innerHTML, who_ + " emits " + JSON.stringify(x)].join("\n");
};}

function fillArrayWithNumbers(n) {
        var arr = Array.apply(null, Array(n));
        return arr.map(function (x, i) { return {prop1: i, prop2:i, prop3:i} });
    }

var sampleObj = {
    beginIndex: "1",
    catId: "111",
    endIndex: "1",
    products: fillArrayWithNumbers(100)
}

console.log('sampleObj', sampleObj);

var result$ = Rx.Observable
  .from(sampleObj.products)
  .bufferWithCount(10)
  .map(function(mini_array){return {
  beginIndex: sampleObj.beginIndex,
  catId: sampleObj.catId,
  endIndex: sampleObj.endIndex,
  products: mini_array
  }})
  .do(emits(ta_result, 'result'));

result$.subscribe(function(){    });

You will then have a stream of objects with arrays of size 10 taken from the array of size 100.



来源:https://stackoverflow.com/questions/34373586/stream-json-with-rxjs-observable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!