2015-10-22 70 views
0

我正在研究节点/ express(基于技术)(Sails,基于技术)的服务,该服务将用于检索大量项目。几次调用将需要返回数千个项目作为JSON序列化数组。如何从节点流式传输JSON?

内部节点将是一个基本的控制循环来检索页面中的项目。每个页面将被检索,执行一些较小的处理,然后将其项目返回给客户端。

目前我正在做一个“存储和转发”的方法,其中每个页面的项目是concat()results数组,然后一旦检索到所有项目,返回结果。

我想要做的更多的是收益率或流式处理方法,其中的项目一旦准备好就添加到响应中 - 避免需要构建大量内存中的集合并开始尽快发送可用数据。

+0

这应该是可行的使用WebSockets。我认为WebSockets是作为一个可写的流实现的,所以你可以为每个出现的块创建'socket.write(json)'。 我不确定,没有时间检查,所以我没有把它作为答案。 –

回答

2

如果您需要从所有数据中生成一个大的JSON字符串,那么您几乎坚持将所有内容都存储在内存中,然后再将其存储在内存中。

另一种方法是将每个项目作为单独的JSON字符串,并使用换行符作为分隔符。这样,只要处理完一个项目,就可以将其串化并使用节点流将其管道化为响应,并且在客户端中,您还可以逐行处理收到的数据。它会去是这样的:

// For each page of data you get, loop over the items like you say 
for item in dataset // Yes that's Coffeescript 

    // Manipulate the item as you need, then make a JSON string out of it 
    jsonStr = JSON.stringify(item) + '\n' 

    // Pipe the string to your http response 
    jsonStr.toStream().pipe(res) // Assuming 'res' is the Express response object 

这不是接近您的问题的唯一途径,但特别是如果你喜欢使用JSON这是最简单的实现方式之一。虽然我对Sails没有任何经验,但我想基本的实现将是一样的。

我希望我的答案可以帮助你,如果不是随意评论。

注意:.toStream()方法来自我的模块streammagic,但当然有其他方法可以从字符串中产生流。

0

您可以直接写信给资源对象明确的是这样

var data=[/* a large array of json objects*/];// 
//let us divide this large array into chunks of smaller array 
function chunk(arr, chunkSize) { 
    var R = []; 
    for (var i = 0; i < arr.length; i += chunkSize) 
     R.push(arr.slice(i, i + chunkSize)); 
    return R; 
} 
var new_data=chunk(data,10);//[/* array of arrays*/], chunk size is 10 
res.writeHead(200, { 
     'Content-Type': 'application/json', 
     'Transfer-Encoding': 'chunked' 
}) 
res.write("["); //array starting bracket 
for (var i = 0; i < new_data.length - 1; i++) { 

     res.write(JSON.stringify(new_data[i]) + ','); 

} 
res.write(JSON.stringify(new_data[new_data.length-i])); 
res.write("]"); //array ending bracket 
res.end();