Node.js JSON 异步解析

Posted

技术标签:

【中文标题】Node.js JSON 异步解析【英文标题】:Node.js JSON async parsing 【发布时间】:2015-01-07 03:42:57 【问题描述】:

例如我有这个文件data.json:

var data = [
  key: "0:0:0:1", val: 25,
  key: "0:0:0:2", val: 1,
  key: "0:0:0:3:0", val: "n/a",
  key: "0:0:0:3:1", val: "n/a",
  key: "0:0:0:4", val: 0,
  key: "0:0:0:5", val: 0
];

我有解析数据时需要使用的 map.json:


  "id": "0:0:0:1",
  "type": "0:0:0:2",
  "coords": 
    "latitude": "0:0:0:3:0",
    "longitude": "0:0:0:3:1"
  ,
  "unixtime": "0:0:0:4",
  "uptime": "0:0:0:5"

我需要的输出是:

"id":25,"type":1,"coords":"latitude":"n/a","longitude":"n/a","unixtime":0,"uptime":0

但是有一个小问题!我不知道如何轻松解析我的 data.json 异步(非阻塞,bla-bla)。实际上它不是 JSON,我不能使用 JSON.parse() 方法。

请帮帮我。告诉我我该怎么做。如何解析该 data.json?

UPD:非常感谢 dandavis!现在我可以解析所有文件并将其用作 javascript 对象。现在我有另一个问题。在 map.json 中,您会看到“坐标”对象。我怎样才能让它 "coords": "latitude": "n/a", "longitude": "n/a" 对吗? 现在我有了这个代码:

var fs = require('fs');

var map = ;
var json = ;

var data = function(data, map) 
  fs.readFile(data, function(err, data) 
    if(err) throw err;

    var evaluated = eval(data+";data");

    evaluated.forEach(function(object) 

      fs.readFile(map, function(err, map) 
        if (err) throw err;

        map = JSON.parse(map, function(key, value) 
          if(object.key === value) 
            console.log(key + " " + object.val);
            json[key] = object.val;
            return(key + " " + object.val);
          
        );

      console.log(json);
      );
    );
  );
;

data('data.json', 'map.json');

我猜这个 forEach 循环阻塞了一些东西。我可以在另一个线程或其他线程中制作这些循环吗?或者也许有我不知道的建议让它变得非常简单和漂亮的代码?如何获取所需格式的 JSON?

【问题讨论】:

你为什么不制作你的data.json文件实际的json(正如它的文件结尾已经暗示的那样)?目前它更像是一个 jsonp 响应,或者只是一个等待 eval()ed 的 .js 脚本。 data=eval(fs.readFileSync("json.json")+";data") 不是“一堆”不必要的逻辑。哎呀;改用 fs.readFile... @dandavis:也许不是“一堆”,但仍然没有必要。格式正确的文件是更好的选择。 @AlexeySlaykovsky:我刚刚测试了 OP 和我的评论中显示的代码,它运行良好。 @sholanozie:我同意好的输入是理想的,但 OP 说这不是一个选项,所以我展示了一个选项... 【参考方案1】:

终于,我做到了!

var fs = require('fs');

var data = function(dataFile, mapFile, done) 
  console.log('Function start');
  fs.readFile(dataFile, function(err, dataString) 
    if(err) return done(err);

    var evaluated = eval(dataString+";data");

    var data = evaluated.reduce(function(data, item) 
      data[item.key] = item.val;
      return data;
    , );

    fs.readFile(mapFile, function(err, mapString) 
      if(err) return done(err);

      var map = JSON.parse(mapString, function(key, value) 
        if(value in data) return data[value];
        return value;
      );

      return done(null, map);
    );
  );
  console.log('Function end');
;

data('data.json', 'map.json', function(err, map) 
  if (err) throw err;

  console.log(JSON.stringify(map));
  console.log('Function success!');
);

【讨论】:

它使用 JSON.parse,它不是异步的【参考方案2】:

这是一个简单的解决方案。你可以检查一下。

var json=require('./test.json')
    _=require('underscore');

var data = [
  key: "0:0:0:1", val: 25,
  key: "0:0:0:2", val: 1,
  key: "0:0:0:3:0", val: "n/a",
  key: "0:0:0:3:1", val: "n/a",
  key: "0:0:0:4", val: 0,
  key: "0:0:0:5", val: 0
];
data=_.indexBy(data,'key');
var match=function(json)
	for(var i in json)
		if(typeof(json[i])==='object')
			match(json[i]);
		else
			for(var j in data)
				if(j === json[i])
					json[i]=data[j].val;
				
			
		
	

match(json);
console.log(json);

'test.json' 是提供的示例 json 文件。

【讨论】:

这不是异步的。 ;(

以上是关于Node.js JSON 异步解析的主要内容,如果未能解决你的问题,请参考以下文章

在 node.js 中使用异步瀑布

在 node.js 中使用异步瀑布

无法在 Node.js 中解析 JSON [重复]

如何从需要 return 语句的 GraphQL 解析器中调用异步 node.js 函数?

使用 Node.js 解析不包含 JSON 对象的 JSON 数组

如何在 Node.js 中解析包含“NaN”的 JSON 字符串