是否有一个用于异步JSON解析器的Node模块,它不会将整个JSON字符串加载到内存中?

时间:2014-10-17 06:47:32

标签: javascript json node.js parsing

我意识到there are a ton of Node modules that provide an async API for parsing JSON,但是他们中的许多人似乎将整个文件或流读入内存,构造一个巨大的字符串,然后将其传递给JSON.parse()。这就是the second answer to "How to parse JSON using NodeJS?" suggests,正是jsonfile module所做的。

构建一个巨大的字符串正是我想要避免的。我想要一个像这样的API:

parseJsonFile(pathToJsonFile): Promise

返回的Promise解析为已解析的JSON对象。此实现应使用恒定的内存量。我对任何类似SAX的东西不感兴趣,因为在解析各种部分时广播事件:只是最终结果。

我认为jsonparse可以做我想做的事情(它显然包括在不使用JSON.parse()的情况下解析JSON的逻辑),但README.md中没有简单的示例,one file in the examples directory 3}}似乎过于复杂。

2 个答案:

答案 0 :(得分:3)

我编写了一个执行此操作的模块:BFJ(Big-Friendly JSON)。它导出了许多在不同抽象级别上运行的函数,但它们都是异步的,并且在它们的核心流式传输。

最高级别是两个用于读取和写入文件系统bfj.readbfj.write的函数。他们每个人都会回复一个承诺,所以你这样称呼他们:

var bfj = require('bfj');

// Asynchronously read from a JSON file on disk
bfj.read(path)
  .then(data => {
    // :)
  })
  .catch(error => {
    // :(
  });

// Asynchronously write to a JSON file on disk
bfj.write(path, data)
  .then(data => {
    // :)
  })
  .catch(error => {
    // :(
  });

此级别还有一个将数据序列化为JSON字符串的函数,称为bfj.stringify

// Asynchronously serialize data to a JSON string
bfj.stringify(data)
  .then(json => {
    // :)
  })
  .catch(error => {
    // :(
  });

在这些下面是两个更通用的函数,用于读取和写入流bfj.parsebfj.streamify。这些作为更高级别功能的基础,但您也可以直接调用它们:

// Asynchronously parse JSON from a readable stream
bfj.parse(readableStream).
  .then(data => {
    // :)
  })
  .catch(error => {
    // :(
  });

// Asynchronously serialize data to a writable stream of JSON
bfj.streamify(data).
  .pipe(writableStream);

在最低级别,有两个与SAX解析器/序列化器bfj.walkbfj.eventify类似的函数。您不太可能想直接调用它们,它们只是更高级别实现的内容。

它是开源和MIT许可的。有关详细信息,请查看the readme

答案 1 :(得分:2)

jsonparse是一个流式json解析器,示例代码已经显示使用节点流的最小值。

  1. client.request()更改为fs.createReadStream()
  2. 在文件读取流上设置on('data')个侦听器,类似于示例中on('response')中的内容。