nodejs - Looping a través de JSON con node.js
nodejs wait foreach (8)
Si usamos nodeJS, definitivamente deberíamos aprovechar las diferentes bibliotecas que proporciona. Las funciones incorporadas como each (), map (), reduce () y muchas más de underscoreJS reducen nuestros esfuerzos. Aquí hay una muestra
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)
})
})
Tengo un archivo JSON que necesito repetir, como se muestra a continuación ...
{
"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
}]
}
Las claves de los datos no siempre serán las mismas (acabo de utilizar ejemplos, hay 20 claves diferentes), y como tal, no puedo configurar mi script para hacer una referencia estática para obtener los valores.
De lo contrario, podría decir
var value1 = json.data.Timestamp;
var value2 = json.data.Start_Value;
var value3 = json.data.Abstract;
etc
En el pasado he usado un bucle foreach simple en el nodo de datos ...
foreach ($json->data as $key => $val) {
switch($key) {
case ''Timestamp'':
//do this;
case: ''Start_Value'':
//do this
}
}
Pero no quiero bloquear el script. ¿Algunas ideas?
Eche un vistazo a Traverse. Recorre recursivamente un árbol de objetos para usted y en cada nodo tiene una cantidad de objetos diferentes a los que puede acceder: clave del nodo actual, valor del nodo actual, padre del nodo actual, ruta de la clave completa del nodo actual, etc. https://github.com/substack/js-traverse . Lo he usado con buenos resultados en objetos a los que quería borrar referencias circulares y cuando necesito hacer un clon profundo mientras transformo varios bits de datos. Aquí hay un código extraído de sus muestras para darle una idea de lo que puede hacer.
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);
Es posible que también desee utilizar hasOwnProperty en el bucle.
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
switch (prop) {
// obj[prop] has the value
}
}
}
node.js es de subproceso único, lo que significa que su script bloqueará si lo quiere o no. Recuerde que el V8 (el motor de Javascript de Google que usa node.js) compila Javascript en código de máquina, lo que significa que la mayoría de las operaciones básicas son realmente rápidas y que recorrer un objeto con 100 claves probablemente tomaría un par de nanosegundos.
Sin embargo, si haces mucho más dentro del ciclo y no quieres que bloquee en este momento , podrías hacer algo como esto
switch (prop) {
case ''Timestamp'':
setTimeout(function() { ... }, 5);
break;
case ''Start_Value'':
setTimeout(function() { ... }, 10);
break;
}
Si su ciclo está haciendo un trabajo intensivo en CPU, necesitará generar un proceso secundario para hacer ese trabajo o utilizar web workers .
Mi forma más preferida es,
var objectKeysArray = Object.keys(yourJsonObj)
objectKeysArray.forEach(function(objKey) {
var objValue = yourJsonObj[objKey]
})
No estoy seguro de si ayuda, pero parece que podría haber una biblioteca para la iteración asíncrona en el nodo alojado aquí:
https://github.com/caolan/async
Async es un módulo de utilidad que proporciona funciones simples y potentes para trabajar con JavaScript asíncrono. Aunque originalmente se diseñó para ser utilizado con node.js, también se puede usar directamente en el navegador.
Async proporciona alrededor de 20 funciones que incluyen los sospechosos "funcionales" habituales (mapa, reducir, filtrar, para cada ...), así como algunos patrones comunes para el flujo de control asíncrono (paralelo, serie, cascada ...). Todas estas funciones asumen que usted sigue la convención node.js de proporcionar una única devolución de llamada como último argumento de su función asíncrona.
Puede iterar a través de objetos de JavaScript de esta manera:
for(var attributename in myobject){
console.log(attributename+": "+myobject[attributename]);
}
myobject podría ser tu json.data
Recomendaría aprovechar el hecho de que nodeJS siempre será ES5. Recuerde que esta no es la gente del navegador en la que puede confiar para que la implementación del idioma sea estable. Dicho esto, recomendaría no utilizar nunca un bucle for-in en nodeJS, a menos que realmente desee recursión profunda en la cadena de prototipos. Para bucles simples y tradicionales, recomendaría hacer un buen uso del método Object.keys en ES5. Si visualiza la siguiente prueba de JSPerf , especialmente si usa Chrome (ya que tiene el mismo motor que nodeJS), obtendrá una idea aproximada de cuánto más rendimiento usará este método que usar un bucle for-in (aproximadamente 10 veces). Más rápido). Aquí hay una muestra del código:
var keys = Object.keys( obj );
for( var i = 0,length = keys.length; i < length; i++ ) {
obj[ keys[ i ] ];
}
Si quiere evitar el bloqueo, que solo es necesario para bucles muy grandes, envuelva el contenido de su bucle en una función llamada así: process.nextTick(function(){<contents of loop>})
, lo que pospondrá la ejecución hasta el próximo tic, dando la oportunidad de que se procesen las llamadas pendientes de otras funciones asincrónicas.