我正在使用async.js在集合上运行for循环。出于性能原因,我想将数据库连接传递给iterator方法,以便它不会在每次迭代器运行时都打开/关闭数据库连接。我正在将mongoose.js用于数据模型。
下面的代码获取mongo中的所有Artists,然后为每位艺术家添加一首歌曲。我的问题是,如何在addArtistSong中使用来自updateAllArtists的相同数据库连接?
function updateAllArtists() {
var db = mongoose.createConnection('localhost/dbname');
var Artist = db.model('Artist', artistSchema);
Artist.find({}, function(err, artists) {
// for each artist, add a song
async.forEach(artists, addArtistSong, function(err) {
});
}
function addArtistSong(artist, cb) {
// THIS IS WHERE I NEED A DB CONNECTION
var Song = db.model('Song', songSchema);
}
我可以以某种方式扩展迭代器签名,例如addArtistSong(artist,db,cb)吗?那我该如何通过forEach调用呢?
最佳答案
一种选择是使数据库连接成为全局变量。但是,如果您不希望这样,可以始终使用闭包在函数之间创建共享变量:
(function(){
// create db in this closure
var db = mongoose.createConnection('localhost/dbname');
function updateAllArtists() {
// now db is available here
var Artist = db.model('Artist', artistSchema);
Artist.find({}, function(err, artists) {
// for each artist, add a song
async.forEach(artists, addArtistSong, function(err) {});
});
}
function addArtistSong(artist, cb) {
// and also available here
var Song = db.model('Song', songSchema);
}
})()
另一种选择是将其作为参数传递给
addArtistSong
。由于async.forEach
期望迭代器函数仅接受2个参数,因此我们可以使用匿名函数包装器将3个参数传递给addArtistSong
:function addArtistSong(db,artist,callback) {
db.model(); //...
}
并在
async.forEach
中调用它:async.forEach(
artists,
function(x,cb){addArtistSong(db,x,cb)},
function(err) {}
);