如何在Mongoose中管理批量保存?我看到它可能还不可能:
Theres有些提到使用像q
这样的流量控制库,但我也注意到mongoose中有promises,它可以用吗?我可以在jQuery Deferred / Promises中做到吗
$.when(obj1.save(), obj2.save(), obj3.save()).then ->
# do something?
答案 0 :(得分:9)
是的,你可以用承诺来做到这一点。如果您使用的是Q promise库,则可以重新编写@ matz3的代码,如:
var tasks = [];
for (var i=0; i < docs.length; i++) {
tasks.push(docs[i].save());
}
Q.all(tasks)
.then(function(results) {
console.log(results);
}, function (err) {
console.log(err);
});
我们在循环中一次启动所有操作,但我们不等待它们中的任何一个完成,因此它们并行运行。我们向数组添加一个promise(对结果来说就像占位符一样)。然后我们等待承诺数组中的所有承诺完成。
大多数好的Promises/A+兼容库都有一些等同于Q.all
答案 1 :(得分:4)
mongoose现在允许您选择Promise实现。
这里我使用node.js默认系统Promise(ES6)烘焙到nodejs
var mongoose = require('mongoose');
mongoose.Promise = global.Promise; // use system implementation
Promise.all(obj1.save(), obj2.save(), obj3.save())
.then(function(resultSaves) {
console.log('parallel promise save result :');
console.log(resultSaves);
mongoose.disconnect();
}).catch(function(err) {
console.log('ERROR on promise save :');
console.log(err);
mongoose.disconnect();
});
node --version V4.1.1
mongoose@4.1.8
答案 2 :(得分:3)
var functions = [];
for (var i=0; i < docs.length; i++) {
functions.push((function(doc) {
return function(callback) {
doc.save(callback);
};
})(docs[i]));
}
async.parallel(functions, function(err, results) {
console.log(err);
console.log(results);
});
答案 3 :(得分:2)
要并行保存多个mongoose文档,您可以执行类似这样的简单操作(假设您有一个名为docs
的文档要保存的数组:
var count = docs.length;
docs.forEach(function(doc) {
doc.save(function(err, result) {
if (--count === 0) {
// All done; call containing function's callback
return callback();
}
});
});
答案 4 :(得分:2)
由于mongoose
现在支持承诺,您可以使用Promise.all().then()
,因此它将在所有承诺得到解决时返回。
Promise.all([
obj1.save(),
obj2.save(),
obj3.save()
])
.then(console.log)
.catch(console.error)
事实上,如果您始终使用save()
方法,则可以在此处使用Array.map()
:
Promise.all([ obj1, obj2, obj3 ].map( obj => obj.save() )
Aaand也使用es6语法来解析生成的数组:
Promise.all([ obj1, obj2, obj3 ].map( obj => obj.save() )
.then( ([ savedObj1, savedObj2, savedObj3 ]) => {
// do something with your saved objects...
})
答案 5 :(得分:1)
关于如何使用async parallel的精炼示例是:
async.parallel([obj1.save, obj2.save, obj3.save], callback);
由于Mongoose中的约定与async(错误,回调)中的约定相同,因此您无需将它们包装在自己的回调中,只需在数组中添加保存调用即可在完成所有操作后获得回调
答案 6 :(得分:-1)
async.queue怎么样 一个简单的例子:
var queue = async.queue(function(obj, callback) {
return obj.save(callback);
});
for (var i in objs) {
var obj = objs[i];
// Some changes on object obj
queue.push(obj);
}
如果在清空队列后需要回调:
var emptyQueue = true;
var queue = async.queue(function(obj, callback) {
return obj.save(callback);
});
queue.drain = function() {
// Every callbacks are finished
// bigCallback();
};
for (var i in objs) {
var obj = objs[i];
// Some changes on object obj
queue.push(obj);
emptyQueue = false;
}
if (emptyQueue) {
// Call manually queue drain in case of the queue is empty
// and we need to call bigCallback() for example
return queue.drain();
}
答案 7 :(得分:-1)
@ForbesLindesay为什么在使用mongoose实现promises并创建自己的All时加载外部库?
创建一个增强mongoose承诺的模块。
var Promise = require("mongoose").Promise;
Promise.all = function(promises) {
var mainPromise = new Promise();
if (promises.lenght == 0) {
mainPromise.resolve(null, promises);
}
var pending = 0;
promises.forEach(function(p, i) {
pending++;
p.then(function(val) {
promises[i] = val;
if (--pending === 0) {
mainPromise.resolve(null, promises);
}
}, function(err) {
mainPromise.reject(err);
});
});
return mainPromise;
}
module.exports = Promise;
然后将它与mongoose一起使用:
require('./promise')
...
var tasks = [];
for (var i=0; i < docs.length; i++) {
tasks.push(docs[i].save());
}
mongoose.Promise.all(tasks)
.then(function(results) {
console.log(results);
}, function (err) {
console.log(err);
});