以递归方式异步解析JSON

时间:2016-01-27 20:31:12

标签: javascript json parsing asynchronous recursion

假设我有这些JSON文件:

company.json

{
  "name" : "Big Corp",
  "employees" : [
    "employees/johnd.json"
  ]
}

员工/ johnd.json

{
  "name" : "John Doe",
  "gender" : "male",
  "contact" : "../contacts/johnd.json"
}

触点/ johnd.json

{
  "email" : "jd@example.com",
}

它们彼此相关,每个以.json结尾的值是指向另一个文件的指针,相对于它当前所在的文件。

在Node中,将这些文件同步连接到树中并不是一项艰巨的任务,但我在找到一个好的异步模式时遇到了一些麻烦。每次我认为我已经以无错误和有效的方式破解它,有些东西再次惹恼我。也许我只是累了。 O_O

我写了一个我想要的完全同步的版本,它完美地运作:

var path = require('path');
var fs = require('fs');

function json(jsonPath) {

  var obj = JSON.parse( fs.readFileSync(jsonPath, 'utf8') );

  recurse(obj, jsonPath);

  return obj;

}

function recurse(obj, fromPath) {

  for (var i in obj) {

    if (isJsonPath(obj[i]))
      obj[i] = json( path.join( path.dirname(fromPath), obj[i]) );

    if (obj[i] != null && typeof obj[i] == 'object')
      recurse(obj[i], fromPath)

  }
}

function isJsonPath (str) {

  return typeof str == 'string' && /.json$/.test(str);

}

console.log( json('company.json') );

上面的代码与前面提到的文件和结构相结合,返回正确的对象:

{
  "name":"Big Corp",
  "employees":[
    {
      "name":"John Doe",
      "gender":"male",
      "contact":{
        "email":"jd@example.com"
      }
    }
  ]
}

SO社区如何将此转变为异步代码?例如,使用readFile而不是readFileSync对文件系统进行异步调用,以便以下内容输出相同的结果:

json('company.json', function (err, data) {

  console.log(data);

});

2 个答案:

答案 0 :(得分:0)

我不是Node的用户,所以我不熟悉它与普通JavaScript相比可以做什么,但是不知道如何尝试。

/ p>

如果检测到JSON路径值,请使用decadeStart varchar2(10) := '01-JAN-' || SUBSTR(FLOOR(to_char(dDate25, 'YYYY')/10)*10,3,1) || 1; DBMS_OUTPUT.PUT_LINE('The decade starts with: ' || decadeStart); 将对象上的该键设置为getter。然后,此getter将执行对Object.defineProperty的调用以获取该文件,并将其自身替换为文件的已解析内容。

这意味着只有在实际需要时才加载文件,即#懒惰加载"。在大多数情况下,即使使用同步文件操作,这也应该很棒。

您生成的对象将如下所示:

json

这可能需要进行一些调整,特别是因为您在那里定义了数组而不是单独的员工列表"文件,但这应该让你大致了解如何延迟加载。

答案 1 :(得分:0)

我会使用异步库来完成这样的任务。

例如async

queue函数看起来可能适合任务,尽管有很多模式可用。文档here