1

我正在使用 async.js 在集合上运行 for 循环。出于性能原因,我想将数据库连接传递给迭代器方法,这样它就不会在每次迭代器运行时打开/关闭数据库连接。我将 mongoose.js 用于我的数据模型。

下面的代码获取 mongo 中的所有艺术家,然后为每个艺术家添加一首歌曲。我的问题是,如何在 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 调用中传递它呢?

4

1 回答 1

2

一种选择是使数据库连接成为全局变量。但是,如果您不希望这样,您始终可以使用闭包在函数之间创建共享变量:

(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) {}
);
于 2012-11-30T03:55:41.207 回答