Seit Javascript 1.7 gibt es ein Iterator Objekt, das dies erlaubt:
var a={a:1,b:2,c:3};
var it=Iterator(a);
function iterate(){
try {
console.log(it.next());
setTimeout(iterate,1000);
}catch (err if err instanceof StopIteration) {
console.log("End of record.\n");
} catch (err) {
console.log("Unknown error: " + err.description + "\n");
}
}
iterate();
gibt es so etwas in node.js?
Im Moment verwende ich:
function Iterator(o){
/*var k=[];
for(var i in o){
k.Push(i);
}*/
var k=Object.keys(o);
return {
next:function(){
return k.shift();
}
};
}
dies führt jedoch zu einem erheblichen Aufwand, da alle Objektschlüssel in k
gespeichert werden.
Was Sie wollen, ist eine langsame Iteration über ein Objekt oder ein Array. Dies ist in ES5 nicht möglich (daher nicht in node.js möglich). Wir werden das irgendwann bekommen.
Die einzige Lösung besteht darin, ein Knotenmodul zu finden, das V8 erweitert, um Iteratoren (und wahrscheinlich Generatoren) zu implementieren. Ich konnte keine Implementierung finden. Sie können sich den Quellcode von Spidermonkey ansehen und versuchen, ihn in C++ als V8-Erweiterung zu schreiben.
Sie können Folgendes versuchen, es werden jedoch auch alle Schlüssel in den Speicher geladen
Object.keys(o).forEach(function(key) {
var val = o[key];
logic();
});
Da Object.keys
jedoch eine native Methode ist, kann dies eine bessere Optimierung ermöglichen.
Wie Sie sehen können, ist Object.keys deutlich schneller. Ob der tatsächliche Speicherplatz optimaler ist, ist eine andere Sache.
var async = {};
async.forEach = function(o, cb) {
var counter = 0,
keys = Object.keys(o),
len = keys.length;
var next = function() {
if (counter < len) cb(o[keys[counter++]], next);
};
next();
};
async.forEach(obj, function(val, next) {
// do things
setTimeout(next, 100);
});
Denken Sie auch daran, dass Sie ein zweites Argument an die Funktion .forEach()
übergeben können, indem Sie das Objekt angeben, das als Schlüsselwort this
verwendet werden soll.
// myOjbect is the object you want to iterate.
// Notice the second argument (secondArg) we passed to .forEach.
Object.keys(myObject).forEach(function(element, key, _array) {
// element is the name of the key.
// key is just a numerical value for the array
// _array is the array of all the keys
// this keyword = secondArg
this.foo;
this.bar();
}, secondArg);
Ich bin zu node.js neu (ungefähr 2 Wochen), aber ich habe gerade ein Modul erstellt, das den Inhalt eines Objekts rekursiv an die Konsole meldet. Es listet alle auf oder sucht nach einem bestimmten Objekt und kann dann bei Bedarf eine bestimmte Tiefe anzeigen.
Vielleicht können Sie dies an Ihre Bedürfnisse anpassen. Halte es einfach! Warum komplizieren? ...
'use strict';
//console.log("START: AFutils");
// Recusive console output report of an Object
// Use this as AFutils.reportObject(req, "", 1, 3); // To list all items in req object by 3 levels
// Use this as AFutils.reportObject(req, "headers", 1, 10); // To find "headers" item and then list by 10 levels
// yes, I'm OLD School! I like to see the scope start AND end!!! :-P
exports.reportObject = function(obj, key, level, deep)
{
if (!obj)
{
return;
}
var nextLevel = level + 1;
var keys, typer, prop;
if(key != "")
{ // requested field
keys = key.split(']').join('').split('[');
}
else
{ // do for all
keys = Object.keys(obj);
}
var len = keys.length;
var add = "";
for(var j = 1; j < level; j++)
{
// I would normally do {add = add.substr(0, level)} of a precreated multi-tab [add] string here, but Sublime keeps replacing with spaces, even with the ["translate_tabs_to_spaces": false] setting!!! (angry)
add += "\t";
}
for (var i = 0; i < len; i++)
{
prop = obj[keys[i]];
if(!prop)
{
// Don't show / waste of space in console window...
//console.log(add + level + ": UNDEFINED [" + keys[i] + "]");
}
else
{
typer = typeof(prop);
if(typer == "function")
{
// Don't bother showing fundtion code...
console.log(add + level + ": [" + keys[i] + "] = {" + typer + "}");
}
else
if(typer == "object")
{
console.log(add + level + ": [" + keys[i] + "] = {" + typer + "}");
if(nextLevel <= deep)
{
// drop the key search mechanism if first level item has been found...
this.reportObject(prop, "", nextLevel, deep); // Recurse into
}
}
else
{
// Basic report
console.log(add + level + ": [" + keys[i] + "] = {" + typer + "} = " + prop + ".");
}
}
}
return ;
};
//console.log("END: AFutils");
Für die einfache Wiederholung von Schlüsseln/Werten können manchmal Bibliotheken wie underscorejs Ihr Freund sein.
const _ = require('underscore');
_.each(a, function (value, key) {
// handle
});
nur als Referenz
seinen Code anpassen:
Object.prototype.each = function(iterateFunc) {
var counter = 0,
keys = Object.keys(this),
currentKey,
len = keys.length;
var that = this;
var next = function() {
if (counter < len) {
currentKey = keys[counter++];
iterateFunc(currentKey, that[currentKey]);
next();
} else {
that = counter = keys = currentKey = len = next = undefined;
}
};
next();
};
({ property1: 'sdsfs', property2: 'chat' }).each(function(key, val) {
// do things
console.log(key);
});