Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 异步递归解析JSON_Javascript_Json_Parsing_Asynchronous_Recursion - Fatal编程技术网

Javascript 异步递归解析JSON

Javascript 异步递归解析JSON,javascript,json,parsing,asynchronous,recursion,Javascript,Json,Parsing,Asynchronous,Recursion,假设我有这些JSON文件: company.json employees/johnd.json 联系人/johnd.json 它们都相互关联,每个以.json结尾的值都是指向另一个文件的指针,相对于当前所在的文件 在Node中,将这些文件同步连接到树中并不是一项困难的任务,但我很难找到一个好的异步模式。每次我认为我已经以一种无bug、高效的方式破解了它,我就会再次被某些东西绊倒。也许我只是累了。欧欧欧 我已经为我想要的东西编写了一个完全同步的版本,它工作得非常完美: var path = req

假设我有这些JSON文件:

company.json

employees/johnd.json

联系人/johnd.json

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

在Node中,将这些文件同步连接到树中并不是一项困难的任务,但我很难找到一个好的异步模式。每次我认为我已经以一种无bug、高效的方式破解了它,我就会再次被某些东西绊倒。也许我只是累了。欧欧欧

我已经为我想要的东西编写了一个完全同步的版本,它工作得非常完美:

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);

});

我不是Node的用户,所以我不知道与常规JavaScript相比,Node能做什么和不能做什么,但这里有一个尝试的想法

如果检测到JSON路径值,请使用
Object.defineProperty
将对象上的键设置为getter。然后,该getter将执行对
json
的调用,以获取该文件,并将其自身替换为该文件的解析内容

这意味着只有在实际需要时才加载文件,也称为“延迟加载”。在大多数情况下,即使使用同步文件操作,这也应该很好

生成的对象将如下所示:

{
  name: "Big Corp",
  _employees: null,
  get employees() {
    if( this._employees === null) {
      this._employees = json("employees/johnd.json");
    }
    return this._employees;
  }
}

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

对于这样的任务,我将使用异步库

比如说


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

@War10ck\ucode>JSON.parse不会将文件读取为OPwants@War10ck注意需要文件系统中的文件…@hindsmost@nooble啊,是的,我错过了。对不起,谢谢你的回答。我不是这个想法的超级粉丝,尤其是因为我将返回JSON格式的结果数据,因此它将失去其函数/方法。啊,是的,在这种情况下,您需要继续“延迟加载”。。。一切。所以它不再懒惰了!这种想法更适合抓取少量数据,而不一定是所有数据。
{
  "name":"Big Corp",
  "employees":[
    {
      "name":"John Doe",
      "gender":"male",
      "contact":{
        "email":"jd@example.com"
      }
    }
  ]
}
json('company.json', function (err, data) {

  console.log(data);

});
{
  name: "Big Corp",
  _employees: null,
  get employees() {
    if( this._employees === null) {
      this._employees = json("employees/johnd.json");
    }
    return this._employees;
  }
}