promised-mongo:无法最终确定 promise
promised-mongo: can't finalize promise
这是我正在处理的一段代码:它将 reddit 帖子保存到 mongoDB 集合。
我正在使用 promised-mongo 库
问题是当 for 循环完成并且所有数据都保存到数据库时,程序不会退出,它继续执行什么都不做,尽管在每个 promised-[=22 的末尾调用 done()
=] 承诺链。
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();
}
我做错了什么?
这里有几个问题:
- 您正在
for
循环中创建多个承诺,但没有跟踪它们
- 您有一个
DB.posts.insert
创建承诺,但您没有等待它
以相反的顺序解决它们:
如果您不return DB.posts.insert
创建的承诺,则在完成之前将无法等待它。你需要return它:
return function(doc){
if(doc) {
console.log('skipping')
} else {
// here
return DB.posts.insert(posts[i]).then(function() {
console.log(arguments);
nSaved++;
});
}
}
并且您还需要跟踪您正在创建的所有承诺,以便您知道它们何时全部完成。一种简单的方法是使用 .map()
将它们映射到一组承诺,然后使用 Promise.all()
等待它们。
假设posts
是一个数组:
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
});
这也消除了您在那里遇到的令人不快的 IIFE 的需要。
这是我正在处理的一段代码:它将 reddit 帖子保存到 mongoDB 集合。
我正在使用 promised-mongo 库
问题是当 for 循环完成并且所有数据都保存到数据库时,程序不会退出,它继续执行什么都不做,尽管在每个 promised-[=22 的末尾调用 done()
=] 承诺链。
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();
}
我做错了什么?
这里有几个问题:
- 您正在
for
循环中创建多个承诺,但没有跟踪它们 - 您有一个
DB.posts.insert
创建承诺,但您没有等待它
以相反的顺序解决它们:
如果您不return DB.posts.insert
创建的承诺,则在完成之前将无法等待它。你需要return它:
return function(doc){
if(doc) {
console.log('skipping')
} else {
// here
return DB.posts.insert(posts[i]).then(function() {
console.log(arguments);
nSaved++;
});
}
}
并且您还需要跟踪您正在创建的所有承诺,以便您知道它们何时全部完成。一种简单的方法是使用 .map()
将它们映射到一组承诺,然后使用 Promise.all()
等待它们。
假设posts
是一个数组:
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
});
这也消除了您在那里遇到的令人不快的 IIFE 的需要。