Reputation: 555
Specifically I'm working with Mongoose and Node, but I guess this is a more conceptual question about asynchronous coding.
I see this example all over Mongoose docs:
product.sold = Date.now();
product.save(function (err, product, numberAffected) {
if (err) ..
})
However, what if
product.save(...)
executes faster than
product.sold = Date.now()
Wouldn't you be saving before updating...? Maybe I'm missing something here (at a conceptual level)? What's keeping this code "safe" in an asynchronous environment.
More specifically I'm using doc.addToSet as the "update" step, and I'd feel much better if it had a callback I could embed the doc.save step in (to ensure async behavior). Thoughts?
PS. I'm not simply using model.update because I need validation.
Upvotes: 0
Views: 351
Reputation: 21
Asynchronous doesn't mean each line gets executed simultaneously. In this case product.sold is getting assigned and finishes like a normal operation, then save is getting called sequentially afterwards.
The asynchronous part happens with product.save. What is happening is you are passing a function as an argument to product.save which is also a function. This is called an anonymous callback. It does not have a name and gets called asynchronously from inside product.save.
Here is how execution would be ordered:
callback.call(...)
, then product.save returnsSo you update product and save it successfully. The anonymous function you pass is not what actually saves it but rather an asynchronous extension to do what you want, i.e. process errors or make sure the correct number of items get saved.
Upvotes: 1
Reputation: 1214
You don't have to worry about the update operation to happen before the save, because it is blocking.
To understand what the difference is between a blocking (synchronous) and non-blocking (asynchronous) operation, take this basic asynchronous code :
function async(callback) {
process.nextTick(callback);
}
async(function() {
console.log('foo');
}
console.log('bar');
This will display in order bar
, then foo
. The key here is the function process.nextTick(cb)
, which will delay the execution of the callback.
Since NodeJS uses only one thread, it will wait for the whole stack of functions to return, then execute the callback in the next loop of the process. Now, if your update operation was asynchronous, you would have to do your save operation in the callback function passed to that operation.
However, since it is not (you can see that from the doc, and generally, the fact that the function is not accepting any callback parameter is a good indication), the execution of the function will be blocked until that update operation returns.
Upvotes: 0