not nodejs node mongoclient example collection async javascript mongodb promise bluebird node-mongodb-native

nodejs - ¿Cómo puedo promisificar el controlador de JavaScript nativo de MongoDB con bluebird?



mongoose (5)

Al usar Promise.promisifyAll() , ayuda a identificar un prototipo de destino si su objeto de destino debe ser instanciado. En el caso del controlador MongoDB JS, el patrón estándar es:

  • Obtiene un objeto Db , utilizando el método estático MongoClient o el constructor Db
  • Call Db#collection() para obtener un objeto Collection .

Entonces, tomando prestado de https://stackoverflow.com/a/21733446/741970 , puede:

var Promise = require(''bluebird''); var mongodb = require(''mongodb''); var MongoClient = mongodb.MongoClient; var Collection = mongodb.Collection; Promise.promisifyAll(Collection.prototype); Promise.promisifyAll(MongoClient);

Ahora usted puede:

var client = MongoClient.connectAsync(''mongodb://localhost:27017/test'') .then(function(db) { return db.collection("myCollection").findOneAsync({ id: ''someId'' }) }) .then(function(item) { // Use `item` }) .catch(function(err) { // An error occurred });

Esto lo lleva bastante lejos, excepto que también ayudará a asegurarse de que los objetos del Cursor devueltos por Collection#find() también sean promisificados. En el controlador MongoDB JS, el cursor devuelto por Collection#find() no se genera a partir de un prototipo. Por lo tanto, puede ajustar el método y promisificar el cursor cada vez. Esto no es necesario si no utiliza los cursores o no desea incurrir en gastos generales. Aquí hay un enfoque:

Collection.prototype._find = Collection.prototype.find; Collection.prototype.find = function() { var cursor = this._find.apply(this, arguments); cursor.toArrayAsync = Promise.promisify(cursor.toArray, cursor); cursor.countAsync = Promise.promisify(cursor.count, cursor); return cursor; }

Me gustaría usar el controlador JS nativo de MongoDB con las promesas de bluebird . ¿Cómo puedo usar Promise.promisifyAll() en esta biblioteca?


Hemos estado utilizando el siguiente controlador en producción desde hace un tiempo. Es esencialmente un envoltorio de promesa sobre el controlador node.js nativo. También agrega algunas funciones auxiliares adicionales.

poseidon-mongo - https://github.com/playlyfe/poseidon-mongo




Sé que esto ha sido respondido varias veces, pero quería agregar un poco más de información sobre este tema. Según la propia documentación de Bluebird, debe usar ''usar'' para limpiar conexiones y evitar fugas de memoria. Gestión de recursos en Bluebird

Miré por todas partes para saber cómo hacer esto correctamente y la información era escasa, así que pensé en compartir lo que encontré después de mucho ensayo y error. Los datos que utilicé a continuación (restaurantes) provienen de los datos de muestra de MongoDB. Puede obtenerlo aquí: MongoDB Import Data

// Using dotenv for environment / connection information require(''dotenv'').load(); var Promise = require(''bluebird''), mongodb = Promise.promisifyAll(require(''mongodb'')) using = Promise.using; function getConnectionAsync(){ // process.env.MongoDbUrl stored in my .env file using the require above return mongodb.MongoClient.connectAsync(process.env.MongoDbUrl) // .disposer is what handles cleaning up the connection .disposer(function(connection){ connection.close(); }); } // The two methods below retrieve the same data and output the same data // but the difference is the first one does as much as it can asynchronously // while the 2nd one uses the blocking versions of each // NOTE: using limitAsync seems to go away to never-never land and never come back! // Everything is done asynchronously here with promises using( getConnectionAsync(), function(connection) { // Because we used promisifyAll(), most (if not all) of the // methods in what was promisified now have an Async sibling // collection : collectionAsync // find : findAsync // etc. return connection.collectionAsync(''restaurants'') .then(function(collection){ return collection.findAsync() }) .then(function(data){ return data.limit(10).toArrayAsync(); }); } // Before this ".then" is called, the using statement will now call the // .dispose() that was set up in the getConnectionAsync method ).then( function(data){ console.log("end data", data); } ); // Here, only the connection is asynchronous - the rest are blocking processes using( getConnectionAsync(), function(connection) { // Here because I''m not using any of the Async functions, these should // all be blocking requests unlike the promisified versions above return connection.collection(''restaurants'').find().limit(10).toArray(); } ).then( function(data){ console.log("end data", data); } );

Espero que esto ayude a alguien más que quería hacer cosas con el libro de Bluebird.