我的目标是通过Mongoose导入大量数据。作为一个新手,我无法通过异步的各种机制正确设置流量控制。很高兴,如果有人能指出适当的解决方案。感谢。
var async = require('async'),
mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
var Cat = mongoose.model('Cat', { name: String });
// Imagine this is a huge array with a million items.
var content = ['aaa', 'bbb', 'ccc'];
var queries = [];
content.forEach(function(name) {
queries.push(function(cb) {
var obj = new Cat({ name: name });
obj.save(function(err) {
console.log("SAVED: " + name);
console.log(err);
});
return true;
});
});
// FAILED: async.parallel adds all content to db,
// but it would exhaust the resource with too many parallel tasks.
async.parallel(queries, function(err, result) {
if (err)
return console.log(err);
console.log(result);
});
// FAILED: save the first item but not the rest
async.waterfall(queries, function(err, result) {
if (err)
return console.log(err);
console.log(result);
});
// FAILED: same as async.waterfall, async.queue saves the first item only
var q = async.queue(function(name, cb) {
var obj = new Cat({ name: name });
obj.save(function(err) {
console.log("SAVED: " + name);
console.log(err);
});
})
q.push(content, function (err) {
console.log('finished processing queue');
});
答案 0 :(得分:4)
我认为eachLimit
或eachSeries
最适合您的情况:
var content = ['aaa', 'bbb', 'ccc'];
async.eachLimit(content, 10, function(name, done) {
var obj = new Cat({ name : name });
obj.save(done);
// if you want to print some status info, use this instead:
//
// obj.save(function(err) {
// console.log("SAVED: " + name);
// console.log(err);
// done(err);
// });
//
}, function(err) {
// handle any errors;
});
使用eachLimit
,您可以并行运行X个查询量(上例中为10个),以加快速度,而不会耗尽资源。 eachSeries
将等待上一次保存,然后继续下一次保存,因此有效地一次保存一个对象。
请注意,使用each*
,您将无法获得包含(已保存)对象的列表(这是一种即兴发生的机制,您对结果不感兴趣,禁止任何错误)。如果您确实需要最后保存的对象列表,则可以使用等效的map*
函数:mapLimit
和mapSeries
。