简体   繁体   中英

MEAN Stack - Delay in query and request?

I'm trying to learn Node.js and writing a web app with the MEAN stack.

As I send on an array of strings containing item data (say, ["one", "two", "three"] ) to the server side, I have the following code to iterate through the array, check if a document with the element already exists in MongoDB, then accordingly create new documents in the database.

server side code:

// items is an array of strings sent from the client side
for (var i = 0; i < items.length; i++) {
        var item_name = items[i];            

        // For each item, find an existing one
        Item.findOne({'name': item_name }, function(err, item) {
            // If not already existing, add to database.
            if (!item) {         
                var new_item = new Item();
                new_item.name = item_name;

                new_item.save(function(err) {
                    if (err) throw err;
                });
            }
        });
    }
}

The problem is that new_item.name always equals the last element in the array, ie "three"

My guess is that the query in the database takes longer than the loop to run, so by the time we're in the callback of findOne() , we've already iterated to the end of the array.

Is this true? If so, what would be a work around for this problem?

I understand that this is potentially be a common question that many may have asked before, but after some time of searching I'm still not able to solve the problem. Please advise.

There's already a comment that says to do this. You can create closure (as below) or create a separate function that's outside of the loop. Here's a little blog post about closures http://jondavidjohn.com/blog/2011/09/javascript-closure-explained-using-events

// items is an array of strings sent from the client side
for (var i = 0; i < items.length; i++) {
  (function(item_name) {    
    // For each item, find an existing one
    Item.findOne({'name': item_name }, function(err, item) {
      // If not already existing, add to database.
      if (!item) {         
        var new_item = new Item();
        new_item.name = item_name;

        new_item.save(function(err) {
          if (err) throw err;
        });
      }
    });
  })(items[i]);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM