1

I'm using the node.js driver for mongodb. I am getting non blocking behavior below. Is this because of the Node.js driver api? Is there a api/option for blocking? I would like to avoid over use of promises and avoid a promise just for array.forEach().

User.prototype.findUsername = function(user) {
  return this.collection.find(user);
};


function deleteUser() {
  var deleteDocs;
  var document = user.findUsername({'username': 'bob123'});
  document.forEach(function(mydoc) {
    mydoc.pets.forEach(function(doc) {
      console.log(doc.data)
      deleteDocs = doc.data;
    });
  })
  return deleteDocs;
}

bob = api.deleteUser();
console.log("outside of the function- "  + bob)

outside of the function- undefined
[ 56da547268b9d17317d05f28 ]
dman
  • 10,406
  • 18
  • 102
  • 201
  • 2
    Handing you the duplicate of the master duplicate since it's title is closest to your statements here. Unless you are importing some co-routine dependency that only "appears" to make a call blocking then you are generally always wrapping the call. So just wrap the return in a promise and resolve that. I already showed you this on another question of yours. – Blakes Seven Mar 05 '16 at 22:01
  • Ok, I will use a promise. But, the context of the question I guess should be... native `.forEach()` is blocking, why is MongoDb Node driver `.forEach()` non blocking? – dman Mar 05 '16 at 22:23
  • 1
    As far as I can tell the array you are running the `.forEach()` on is an embedded document ( is was in all your previous questions ). And therefore there is nothing async to happen there. Only the actual `.findUserName()` is the async part. But of course since "that" call is async, then your whole wrapping function really needs to use a promise or callback. Just like the linked duplicate says. – Blakes Seven Mar 06 '16 at 01:48
  • 1
    So subsequently, since you did not close the question, you just gave someone a reward for providing information that is not actually relevant to the question, when instead you should have understood the duplicate contents and accepted the marked duplicate as the answer instead. You just cannot simply turn a non-blocking operation into something that blocks. – Blakes Seven Mar 06 '16 at 01:53
  • I don't get this behavior with `update()`. Why is this.collection.update() a blocking operation but this.collection.find() is not? Even though update() returns a promise, it 'doesn't turn a async operation into sync', as you say. If `update()` is not async to begin with, it should not be wrapped in a promise. – dman Mar 06 '16 at 03:03

1 Answers1

2

MongoDB's forEach is synchronous, because it performs IO, which is (generally) asynchronous in node.js. Native forEach (Array.prototype.forEach) doesn't perform any IO and that's why it's synchronous.

vkurchatkin
  • 13,364
  • 2
  • 47
  • 55
  • This is very interesting..... never thought about this. Is this for sure though? I thought in native JS `forEach` forces the sync behavior. – dman Mar 05 '16 at 22:55
  • 1
    Unfortunately the OP @dman here did not really make it clear in there question ( nor likely understood ) that it is not the `.forEach()` part that has any async function. As the code here and from previous questions from the OP suggests, this is just a regular array and there is not even anything here to suggest that this was a "Cursor" from which [`.forEach()`](http://mongodb.github.io/node-mongodb-native/2.1/api/Cursor.html#forEach) is a method for iterating. So you actually kind of missed the mark here. The basic question and answer are as in the marked duplicate. – Blakes Seven Mar 06 '16 at 01:50
  • 1
    well, `find` returns a `Cursor` object, which has asynchronous `forEach` method, so I'm not sure what you mean – vkurchatkin Mar 06 '16 at 12:43