简体   繁体   English

使用RxJS Observable流JSON

[英]Stream JSON with RxJS Observable

I'm trying to understand a few things about RxJs. 我试图了解有关RxJ的一些信息。 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. 我想要做的是消耗一些JSON数据,并在传入时立即开始在DOM上呈现这些数据。我已经设置了流请求,响应和显示。 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]

}

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 ). 阅读完文件后,您需要找到一种方法来使文件中的对象流代替一个大对象( 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.?). 其机制将首先取决于源的结构(文件和文件读取机制),而不是Rxjs(每一行都是可以导致信息显示等的对象吗?)。 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.?) 一旦有了“最小的可显示信息单元”,就可以使用Rxjs对其进行缓冲/处理(是否要为每个对象或每100个对象显示某些内容,或者删除不必要的属性等?)
  2. you need to update your display incrementally as new data arrive. 您需要在新数据到达时逐步更新显示内容。 That means you need something like $resultList.html($resultList.html() + compiledTemplate(response)); 这意味着您需要类似$resultList.html($resultList.html() + compiledTemplate(response)); to append the new compiled html to the old one. 将新编译的html附加到旧的html

UPDATE : for chunking an array, you can have a look at this jsfiddle : http://jsfiddle.net/429vw0za/ 更新:对于对数组进行分块,您可以查看以下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. 然后,您将获得大小为10的数组的对象流,大小为10。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM