如何从节点流式传输 JSON?

STW*_*STW 9 streaming json node.js express sails.js

我正在开发基于节点/快递(Sails,技术上)的服务,该服务将用于检索大量项目。多次调用需要将数千个项目作为 JSON 序列化数组返回。

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

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

我想做的更多是一种产出或流媒体方法,其中项目一旦准备好就被添加到响应中——避免构建大型内存集合并开始发送可用数据作为尽快。

Raj*_*rma 6

您可以使用类似这样的内容直接写入res对象

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();
Run Code Online (Sandbox Code Playgroud)

在客户端使用这样的东西

// using axios
var url = 'http://localhost:3000';
axios.get(url, { responseType: 'stream' }).then(handleRes);

function handleRes(res) {
    // res.headers available here
    res.data.on('data', data => {
        data = data.toString(); // utf8 by default, change if needed

        if (data === '[' || data === ']') return console.log(data);

        var jsonStr = data.slice(-1) === '}' ? data : data.slice(0, -1);
        console.log(JSON.parse(jsonStr));
    })
}
Run Code Online (Sandbox Code Playgroud)