Reputation: 530
Here's a piece of code I'm working at: it saves reddit posts to mongoDB collection.
I'm using promised-mongo library
The problem is when the for loop completes and all data is saved to database, program does not exit, it continues executing doing nothing, despite of done()
called at the end of each promised-mongo promise chain.
for (var i = 0; i< posts.length; i++) {
posts[i].done = false;
DB.posts.findOne({
"id" : posts[i].id // it's 'id', not mongo's '_id'
})
.then(function(i) {
return function(doc){
if(doc) {
console.log('skipping')
} else {
DB.posts.insert(posts[i]).then(function() {
console.log(arguments);
nSaved++;
});
}
}
}(i))
.catch(function(){
console.log(arguments)
})
.done();
}
What am I doing wrong?
Upvotes: 0
Views: 562
Reputation: 101738
There are a few problems here:
for
loop, but not keeping track of themDB.posts.insert
that creates a promise, but you are not awaiting itTo address them in reverse order:
If you don't return the promise created by DB.posts.insert
there will be no way of awaiting it until it is done. You need to return it:
return function(doc){
if(doc) {
console.log('skipping')
} else {
// here
return DB.posts.insert(posts[i]).then(function() {
console.log(arguments);
nSaved++;
});
}
}
And you also need to keep track of all the promises you are creating, so that you know when they are all done. An easy way to do this is to use .map()
to map them to an array of promises, and then use Promise.all()
to await them.
Assuming that posts
is an array:
function ensurePost(post) {
post.done = false;
return DB.posts.findOne({
"id" : post.id // it's 'id', not mongo's '_id'
})
.then(function(doc){
if(doc) {
console.log('skipping ' + post.id)
} else {
return DB.posts.insert(post).then(function() {
console.log(arguments);
nSaved++;
});
}
})
.catch(function(error){
console.error('Error inserting', post.id, error);
});
}
Promise.all(posts.map(ensurePost))
.done(function () {
// all done. close the connection
});
This also eliminates the need for that unpleasant IIFE you had there.
Upvotes: 3