Javascript 异步递归解析JSON
假设我有这些JSON文件: company.json employees/johnd.json 联系人/johnd.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
结尾的值都是指向另一个文件的指针,相对于当前所在的文件
在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;
}
}