Перебирайте ключи объектов в узле.js
Так как Javascript 1.7 есть итератор объект, который позволяет это:
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();
есть что-то вроде этого в узле.Джей ?
прямо сейчас я использую:
function Iterator(o){
/*var k=[];
for(var i in o){
k.push(i);
}*/
var k=Object.keys(o);
return {
next:function(){
return k.shift();
}
};
}
но это создает много накладных расходов на хранение все ключи объекта в k
.
4 ответа:
то, что вы хотите, это ленивая итерация над объектом или массивом. Это невозможно в ES5 (таким образом, невозможно в узле.js). Мы получим это в конце концов.
единственное решение-найти модуль узла, который расширяет V8 для реализации итераторов (и, вероятно, генераторов). Я не мог найти никакой реализации. Вы можете посмотреть исходный код spidermonkey и попробовать написать его на C++ как расширение V8.
вы можете попробовать следующее, однако он также будет загружать все ключи в
Object.keys(o).forEach(function(key) { var val = o[key]; logic(); });
вместе с
Object.keys
- это собственный метод, который может обеспечить лучшую оптимизацию.как вы можете видеть объект.ключи значительно быстрее. Является ли фактическое хранение памяти более оптимальным-это другой вопрос.
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); });
также помните, что вы можете передать второй аргумент
.forEach()
функция, указывающая объект для использования в качествеthis
ключевое слово.// 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);
Я новичок в узел.js (около 2 недель), но я только что создал модуль, который рекурсивно сообщает консоли содержимое объекта. Он будет перечислять все или искать конкретный элемент, а затем детализировать на заданную глубину, если это необходимо.
возможно, вы можете настроить это в соответствии с вашими потребностями. Держите Его Просто! Зачем усложнять?...
'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");
изменить его код:
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); });