30052

Looping Array and checking MongoDB collection in loop (Async)

Question:

I'm having a little bit of an issue with some asynchronus looping with calls to mongodb. I have tried several approaches and looked into libraries such as async and co-monk. (I'm using monk as my connection etc).

I have an array of data that I need to pass through to a mongo collection to check its ok etc..My background is PHP/Sql, so the async nature of mongo is a little hard to get my head around.

Some basic sudo code of what I'm trying to do:

function check (collection) { var records = { { body: "Test 1"}, { body: "Test 2" } }; for (var i in records) { collection.find({ body: records[i].body }, {}, function (e, rows) { console.log(rows); }); } }

It only executes on the final loop of the records. I know this is due to the async nature of JS, but how do I structure it properly to work like this?

Thanks,

Answer1:

The general key to asynchronous processing is that you want to have some indication of when the current iteration is done before moving on to the next iteration. Since the actual operations such as .find() here themselves employ a "callback" which is "called" when the operation is completed with a response, then what you usually want to do is call something that signifies your end of iteration in the same section of code.

In a basic way, you can get a similar result as you can in traditional loops with the <a href="https://github.com/caolan/async#eachSeries" rel="nofollow">"async.eachSeries"</a> method, which will only let "one iteration at a time" take place:

function check (collection) { var records = [ { body: "Test 1"}, { body: "Test 2" } ]; async.eachSeries(records,function(item,callback) { collection.find( item, function (err, rows) { console.log(rows); callback(err) }); },function(err) { if (err) throw err; console.log("done"); }); }

So each of the array arguments are passed in to the "iterator" function here as a "item" parameter, and a second argument is a "callback" function to be used later. Every time the iterator is called, that argument is passed to the .find() method which in turn has a "callback" of its own, where the "error" or "documents" response is given.

Inside that callback, the "callback" provided by the "iterator" function is then called to signal the completion of that current iteration. This allows the "each" function here to continue and indeed call the next "iteration" and process the next array element.

Noting your background, be aware of the correct way to notate an "array" in JavaScript with the [] brackets as shown. This is generally an important difference when working with arrays.

There are other variations of <a href="https://github.com/caolan/async#eacharr-iterator-callback" rel="nofollow">"async.each"</a> and <a href="https://github.com/caolan/async#eachlimitarr-limit-iterator-callback" rel="nofollow">"async.eachLimit"</a> which both allow some degree of parallel processing, but the "Series" method does things "in order" in a way that you are used to with traditional loops.

So where loop operations are "non-blocking", you need to signify when that loop completes before you want to move on.

Recommend

  • How to fetch column names from 'MySQL Create Table' Query string?
  • Is there any way of quickening monkeyrunner script execution?
  • Android Chronometer starts and stops but carries on counting when stopped
  • MAVEN : Run Multiple Maven Project using Maven Test
  • SQL: Getting the physical size of a subset of a table
  • C# - Most efficient way to iterate through multiple arrays/list
  • How do I remove all but some records based on a threshold?
  • Consuming a WCF service in a Java Client using wsHttpBinding
  • How do I get the list of bad records that didn't load in Bigquery?
  • Sequential (transactional) API calls in angular 4 with state management
  • presentShareDialogWithParams posts to FB wall, but callback handler results say error
  • Detect when Facebook like button is clicked
  • Needing to do .toArray() to get output of mongodb .find() on key name not value
  • Mysterious problem with floating point in LISP - time axis generation
  • Make VS2015 use angular-cli ng at build time in a .NET project
  • How to know when stdin is empty if it contains EOF?
  • how to adjust image in a panel in Java swing?
  • Possible to stop flickering java tooltip in heavyweight mode?
  • vba code to select only visible cells in specific column except heading
  • Can a Chrome extension content script make an jQuery AJAX request for an html file that is itself a
  • Upload files with Ajax and Jquery
  • Timeout for blocking function call, i.e., how to stop waiting for user input after X seconds?
  • Do I've to free mysql result after storing it?
  • How to pass list parameters for each object using Spring MVC?
  • Transpose CSV data with awk (pivot transformation)
  • SetUp method failed while running tests from teamcity
  • How to delete a row from a dynamic generate table using jquery?
  • AngularJs get employee from factory
  • Proper way to use connect-multiparty with express.js?
  • using HTMLImports.whenReady not working in chrome
  • JTable with a ScrollPane misbehaving
  • What are the advantages and disadvantages of reading an entire file into a single String as opposed
  • Authorize attributes not working in MVC 4
  • EntityFramework adding new object to nested object collection
  • Sorting a 2D array using the second column C++
  • Reading document lines to the user (python)
  • Binding checkboxes to object values in AngularJs
  • Net Present Value in Excel for Grouped Recurring CF
  • jQuery Masonry / Isotope and fluid images: Momentary overlap on window resize
  • How to load view controller without button in storyboard?