質問

I'm relatively new to nodeJS/Javascript's asynchronous nature (Python background) and trying am trying to figure how to step through a nested JSON object, extract it's values using asnyc.js.

I came across this snippet, How to navigate in nested JSON.

function recursiveGetProperty(obj, lookup, callback) {
    for (property in obj) {
        if (property == lookup) {
            callback(obj[property]);
        } else if (obj[property] instanceof Object) {
            recursiveGetProperty(obj[property], lookup, callback);
        }
    }
}

Which works great with this sample object, foo.

var foo = {
  'key_1' : 'val1',
  'key_2': {
    'key_3': 'val3',
    'key_4': 'val4'
  }
}

recursiveGetProperty(foo, 'key_1', function(obj) {
  console.log(obj);
});

returns 'val1'

recursiveGetProperty(foo, 'key_3', function(obj) {
  console.log(obj);
});

returns 'val3'

This is exactly what I needed but when I feed it key values via iteration:

var keys = ['val1', 'val3'];

for (var keys in keys) {
  recursiveGetProperty(foo, keys, function(obj) {
    console.log(obj);
  });
}

nothing is logged to console. so I wrote a logging function:

function log(obj) {
  console.log(obj);
}

and tried:

for (var key in keys) {
  recursiveGetProperty(foo, keys, log(obj));
}

but i get ReferenceError: obj is not defined.

I was told it's not a great idea to execute a callback inside a for loop, I'm not exactly sure why so I looked into async.js. It seems like the right solution for what I want but I have no idea how to go about it.

Using async.js, I would like to build a series of recursiveGetProperty functions, store them in an array, and then execute those calls asynchronously but I'm stumped on how to approach the problem.

What I would ultimately want is something like this:

async.each(['key_1', 'key_2', 'key_3'], recursiveGet(key) {
  doSomethingWithData();
}, function(err) {
  doSomethingWhenDone();
});

This would be used on an ExpressJS server to parse JSON and do something with it afterwards.

Any help or suggestion would be greatly appreciated.

役に立ちましたか?

解決

There are bug in this code

var keys = ['val1', 'val3'];
for (var keys in keys) {
    recursiveGetProperty(foo, keys, function(obj) {
        console.log(obj);
    });
}
  • The array of keys (line 1) is overwritten by the keys index (line 2) of the for loop. So let's rename that key.
  • For an iterated array a key would be a number (0, 1, ..., n), not a string. You need to use those numbers as indices to keys
  • Also your recursiveGetProperty finds by keys not values.

So the code should be

var keys = ['key_1', 'key_2'];
for (var key in keys) {
    recursiveGetProperty(foo, keys[key], function(obj) {
        console.log(obj);
    });
}

他のヒント

var keys = ['key_1', 'key_2'];

keys.forEach(function (key) {
  recursiveGetProperty(foo, key, function(obj) {
    console.log(obj);
  });
});

http://jsfiddle.net/fPRQK/

Issues in your code:

  • for(var key in obj) works with object properties only, not with array values. Use Array.forEach or a regular for loop instead.
  • recursiveGetProperty(foo, keys, log(obj)): This would call log instantly and pass it's return value to recursiveGetProperty. You could either pass just log or function (obj) { log(obj); }, which in this case mean the same. Also in this case what you want to pass is key.
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top