112

いくつかの mongodb コレクションを削除したいのですが、それは非同期タスクです。コードは次のようになります。

var mongoose = require('mongoose');

mongoose.connect('mongo://localhost/xxx');

var conn = mongoose.connection;

['aaa','bbb','ccc'].forEach(function(name){
    conn.collection(name).drop(function(err) {
        console.log('dropped');
    });
});
console.log('all dropped');

コンソールに次のように表示されます。

all dropped
dropped
dropped
dropped

all droppedすべてのコレクションがドロップされた後に印刷されることを確認する最も簡単な方法は何ですか? コードを簡素化するために、任意のサードパーティを使用できます。

4

8 に答える 8

129

Promiseを使用します。

var mongoose = require('mongoose');

mongoose.connect('your MongoDB connection string');
var conn = mongoose.connection;

var promises = ['aaa', 'bbb', 'ccc'].map(function(name) {
  return new Promise(function(resolve, reject) {
    var collection = conn.collection(name);
    collection.drop(function(err) {
      if (err) { return reject(err); }
      console.log('dropped ' + name);
      resolve();
    });
  });
});

Promise.all(promises)
.then(function() { console.log('all dropped)'); })
.catch(console.error);

これにより、各コレクションがドロップされ、各コレクションの後に「ドロップされました」と出力され、完了すると「すべてドロップされました」と出力されます。エラーが発生した場合は に表示されstderrます。


以前の回答 (これは Node の Promises のネイティブ サポートより前の日付です):

QプロミスまたはBluebirdプロミスを使用します。

Qの場合:

var Q = require('q');
var mongoose = require('mongoose');

mongoose.connect('your MongoDB connection string');
var conn = mongoose.connection;

var promises = ['aaa','bbb','ccc'].map(function(name){
    var collection = conn.collection(name);
    return Q.ninvoke(collection, 'drop')
      .then(function() { console.log('dropped ' + name); });
});

Q.all(promises)
.then(function() { console.log('all dropped'); })
.fail(console.error);

ブルーバードの場合:

var Promise = require('bluebird');
var mongoose = Promise.promisifyAll(require('mongoose'));

mongoose.connect('your MongoDB connection string');
var conn = mongoose.connection;

var promises = ['aaa', 'bbb', 'ccc'].map(function(name) {
  return conn.collection(name).dropAsync().then(function() {
    console.log('dropped ' + name);
  });
});

Promise.all(promises)
.then(function() { console.log('all dropped'); })
.error(console.error);
于 2012-05-22T21:13:35.163 に答える
8

@freakish answer を拡張すると、 async は each メソッドも提供します。これは、特にあなたのケースに適しているようです:

var async = require('async');

async.each(['aaa','bbb','ccc'], function(name, callback) {
    conn.collection(name).drop( callback );
}, function(err) {
    if( err ) { return console.log(err); }
    console.log('all dropped');
});

IMHO、これにより、コードがより効率的で読みやすくなります。私は自由に削除しましたconsole.log('dropped')-必要に応じて、代わりにこれを使用してください:

var async = require('async');

async.each(['aaa','bbb','ccc'], function(name, callback) {
    // if you really want the console.log( 'dropped' ),
    // replace the 'callback' here with an anonymous function
    conn.collection(name).drop( function(err) {
        if( err ) { return callback(err); }
        console.log('dropped');
        callback()
    });
}, function(err) {
    if( err ) { return console.log(err); }
    console.log('all dropped');
});
于 2013-05-28T08:34:42.883 に答える
5

私は外部ライブラリなしでこれを行います:

var yourArray = ['aaa','bbb','ccc'];
var counter = [];

yourArray.forEach(function(name){
    conn.collection(name).drop(function(err) {
        counter.push(true);
        console.log('dropped');
        if(counter.length === yourArray.length){
            console.log('all dropped');
        }
    });                
});
于 2013-12-27T14:19:12.853 に答える
4

すべての答えはかなり古いです。2013 年の初めから、Mongoose はすべてのクエリに対してPromise を徐々にサポートし始めたので、必要な順序でいくつかの非同期呼び出しを構造化する推奨される方法になると思います。

于 2013-11-06T09:27:03.377 に答える
0

(別の約束/延期された実装)を使用deferredすると、次のことができます。

// Setup 'pdrop', promise version of 'drop' method
var deferred = require('deferred');
mongoose.Collection.prototype.pdrop =
    deferred.promisify(mongoose.Collection.prototype.drop);

// Drop collections:
deferred.map(['aaa','bbb','ccc'], function(name){
    return conn.collection(name).pdrop()(function () {
      console.log("dropped");
    });
}).end(function () {
    console.log("all dropped");
}, null);
于 2012-07-12T19:32:00.113 に答える
0

Babel などのトランスパイラを使用していて、async/await を使用している場合は、次のようにできます。

function onDrop() {
   console.log("dropped");
}

async function dropAll( collections ) {
   const drops = collections.map(col => conn.collection(col).drop(onDrop) );
   await drops;
   console.log("all dropped");
}
于 2016-03-12T16:20:19.567 に答える