All the calls to your callback will happen after all the iterations of the loop have taken place, so when they get executed the value of key will be whatever is its last value.
One common solution is to wrap all your calls in a closure:
for(key in object){
(function(key, value) {
db.collection.findOne(criteria, function(err, doc){
// ...
db.collection.insert(...);
})
})(key, object[key]);
};
Another way you could achieve the same thing is to use the Object.keys() method (which creates an array out of the keys in your object) and call Array#forEach on the array. That way you can skip the extra closure because forEach already has a function callback:
Object.keys(object).forEach(function(key) {
db.collection.findOne(criteria, function(err, doc){
// ...
db.collection.update(...);
})
});
Which is arguably a bit more elegant