使用node.js循环浏览JSON

我有一个JSON文件,我需要迭代,如下所示…

{ "device_id": "8020", "data": [{ "Timestamp": "04-29-11 05:22:39 pm", "Start_Value": 0.02, "Abstract": 18.60, "Editor": 65.20 }, { "Timestamp": "04-29-11 04:22:39 pm", "End_Value": 22.22, "Text": 8.65, "Common": 1.10, "Editable": "true", "Insert": 6.0 }] } 

数据中的键不总是相同的(我刚刚使用了示例,有20个不同的键),因此,我无法设置我的脚本来静态引用它们来获取值。

否则,我可以说

 var value1 = json.data.Timestamp; var value2 = json.data.Start_Value; var value3 = json.data.Abstract; etc 

在过去,我在数据节点上使用了一个简单的foreach循环。

 foreach ($json->data as $key => $val) { switch($key) { case 'Timestamp': //do this; case: 'Start_Value': //do this } } 

但不想阻止脚本。 有任何想法吗?

你可以用这种方法遍历JavaScript对象:

 for(var attributename in myobject){ console.log(attributename+": "+myobject[attributename]); } 

myobject可能是你的json.data

你也可以在循环中使用hasOwnProperty 。

 for (var prop in obj) { if (obj.hasOwnProperty(prop)) { switch (prop) { // obj[prop] has the value } } } 

node.js是单线程的,这意味着你的脚本将会阻止你是否需要它。 请记住,V8(node.js使用的Google的Javascript引擎)将JavaScript编译成机器代码,这意味着大多数基本操作都非常快,并且通过一个具有100个键的对象循环可能需要几个纳秒。

但是,如果你在循环中做了很多事情,并且你现在不想阻止它,你可以做这样的事情

 switch (prop) { case 'Timestamp': setTimeout(function() { ... }, 5); break; case 'Start_Value': setTimeout(function() { ... }, 10); break; } 

如果你的循环正在做一些非常耗费CPU的工作,你将需要产生一个subprocess来完成这个工作或者使用networking工作者 。

我会build议利用nodeJS总是ES5的事实。 记住,这不是浏览器的人,你可以依靠稳定的语言的实现。 这就是说我会build议不要在nodeJS中使用for-in循环,除非你真的想在原型链上进行深度recursion。 对于简单的传统循环,我build议在ES5中使用Object.keys方法。 如果您查看以下JSPerftesting ,尤其是在使用Chrome(因为它与nodeJS具有相同的引擎)时,您将会大致了解使用此方法的性能比使用for-in循环(大约10倍更快)。 这是一个代码示例:

  var keys = Object.keys( obj ); for( var i = 0,length = keys.length; i < length; i++ ) { obj[ keys[ i ] ]; } 

如果你想避免阻塞,这只是非常大的循环所必需的,然后把你的循环的内容包装在一个叫做这样的函数中: process.nextTick(function(){<contents of loop>}) ,这会延迟执行直到下一个滴答声,为来自其他asynchronousfunction的未决呼叫提供处理机会。

如果我们使用nodeJS,我们应该充分利用它提供的不同库。 像(),map(),reduce()等内置函数可以减less我们的工作量。 这是一个示例

  var _=require("underscore"); var fs=require("fs"); var jsonObject=JSON.parse(fs.readFileSync('YourJson.json', 'utf8')); _.map( jsonObject, function(content) { _.map(content,function(data){ if(data.Timestamp) console.log(data.Timestamp) }) }) 

不知道是否有帮助,但看起来像这里托pipe的节点中可能有asynchronous迭代库:

https://github.com/caolan/async

Async是一个实用程序模块,它为asynchronousJavaScript提供了直接,强大的function。 虽然最初devise用于node.js,但它也可以直接在浏览器中使用。

asynchronous提供了大约20个函数,包括通常的“function”嫌疑人(map,reduce,filter,for each ……)以及一些用于asynchronous控制stream(parallel,series,waterfall …)的常见模式。 所有这些函数都假定您遵循提供单个callback的node.js约定作为asynchronous函数的最后一个参数。

看一下Traverse。 它会recursion地为你走一个对象树,在每个节点你有许多不同的对象你可以访问 – 当前节点的键,当前节点的值,当前节点的父节点,当前节点的全键path等。https: //github.com/substack/js-traverse 。 我已经使用它来对我想要擦除循环引用的对象产生良好的效果,以及何时需要在转换各种数据位时进行深度克隆。 这里有一些代码从他们的样品拉来给你一个它可以做的味道。

 var id = 54; var callbacks = {}; var obj = { moo : function () {}, foo : [2,3,4, function () {}] }; var scrubbed = traverse(obj).map(function (x) { if (typeof x === 'function') { callbacks[id] = { id : id, f : x, path : this.path }; this.update('[Function]'); id++; } }); console.dir(scrubbed); console.dir(callbacks);