Overview
So I have pulled out a document from my database. Inside is a nested collection of objects. Each of the objects inside this nested collection has an ‘_id’ attribute. I want to find one on these objects specifically by its ‘_id’ using Javascript.
Example
http://jsfiddle.net/WilsonPage/tNngT/
Alternative Example
http://jsfiddle.net/WilsonPage/tNngT/3/
Questions
- Is my example the best way of achieving this?
- Will this block in Node.js?
Yes, if you only know a specific value which is contained by one of your objects (which are held in an Array) you need to loop over the whole structure and compare those values.
As you also did right, break the iteration when you found one (
returnin your example).So my answer to your first question would be yes, in terms of performance this is the right and best way.
What I don’t get is the “Async” example. You just moved the code and changed the structure. Your code is still “blocking” since you’re using a normal
for-loopto search. If that array would be huge, it would block your node-app for the amount of time the loop needs to finish.To really make it asynchronously, you would need to get rid of any
loop. You would need to loop over the structure with a runway-timer.And then use it like
This technique (which is a simplified example), we are creating an self-invoking anonymous function and we pass in the first array item (using
.shift()). We do our comparison and if we found the item we are looking for, execute a callback function the caller needs to provide. If we don’t have a match but the array still contains elements (check for the.length), we create a timeout of 25ms usingsetTimeoutand call our_loopfunction again, this time with the next array item, because.shift()gets and removes the first entry. We repeat that until either no items are left or we found the element. SincesetTimeoutgives other tasks in the JS main thread (on a browser, the UI thread) the chance to do things, we don’t block and screw up the whole show.As I said, this can get optimized. For instance, we can use a
do-whileloop within the_loop()method and also useDate.now()to do things until we go over the 50ms mark for instance. If we need longer than that, create atimeoutthe same way and repeat the above described operation again (so its like, do as much operation as possible within 50ms).