13

我有一个场景,我需要从我的 Node.js/Express RESTful API 返回一个非常大的对象,转换为 JSON 字符串。

res.end(JSON.stringify(obj));

但是,这似乎不能很好地扩展。具体来说,它在我的测试机器上运行良好,有 1-2 个客户端连接,但我怀疑当许多客户端同时请求大型 JSON 对象时,此操作可能会占用 CPU 和内存。

我一直在寻找一个异步 JSON 库,但我发现的唯一一个似乎有问题(具体来说,我得到一个 [RangeError])。不仅如此,它还以一大块的形式返回字符串(例如,对整个字符串调用一次回调,这意味着内存占用不会减少)。

我真正想要的是 JSON.stringify 函数的完全异步管道/流版本,这样它就可以在将数据直接打包到流中时写入数据......从而节省了我的内存占用,也避免了消耗 CPU一种同步方式。

4

2 回答 2

10

理想情况下,您应该按自己的方式流式传输数据,而不是将所有内容都缓冲到一个大对象中。如果你不能改变它,那么你需要将 stringify 分解成更小的单元,并允许主事件循环使用setImmediate处理其他事件。示例代码(我假设主对象有很多顶级属性并使用它们来拆分工作):

function sendObject(obj, stream) {
    var keys = Object.keys(obj);
    function sendSubObj() {
       setImmediate(function(){
          var key = keys.shift();
          stream.write('"' + key + '":' + JSON.stringify(obj[key]));
          if (keys.length > 0) {
            stream.write(',');
            sendSubObj();
          } else {
            stream.write('}');
          }
       });
    })
    stream.write('{');
    sendSubObj();
} 
于 2012-11-22T00:09:32.813 回答
5

听起来您想要 Dominic Tarr 的JSONStream。显然,将它与 express 合并需要一些程序集。

但是,如果您试图序列化(Stringify)对象的 CPU 最大化,那么将该工作分成块可能并不能真正解决问题。流式处理可能会减少内存占用,但不会减少所需的“工作”总量。

于 2012-11-21T23:59:40.057 回答