Come posso promettere il driver Javascript nativo MongoDB usando bluebird?

Mi piacerebbe usare il driver JS nativo di MongoDB con promesse bluebird . Come posso usare Promise.promisifyAll() su questa libreria?

La documentazione della 2.0 filiale contiene una migliore guida alla promise https://github.com/petkaantonov/bluebird/blob/master/API.md#promisification

In realtà ha un esempio di mongodb che è molto più semplice:

 var Promise = require("bluebird"); var MongoDB = require("mongodb"); Promise.promisifyAll(MongoDB); 

Quando si utilizza Promise.promisifyAll() , è utile identificare un prototipo di destinazione se l’object target deve essere istanziato. Nel caso del driver JS MongoDB, il modello standard è:

  • Ottieni un object Db , usando il metodo statico MongoClient o il costruttore Db
  • Chiama Db#collection() per ottenere un object Collection .

Quindi, prendendo a prestito da https://stackoverflow.com/a/21733446/741970 , puoi:

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

Ora puoi:

 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 }); 

Questo ti porta piuttosto lontano, tranne che ti aiuterà anche ad assicurarti che anche gli oggetti Cursor restituiti da Collection#find() siano promessi. Nel driver JS MongoDB, il cursore restituito da Collection#find() non è stato creato da un prototipo. Quindi, puoi avvolgere il metodo e promettere il cursore ogni volta. Questo non è necessario se non si utilizzano i cursori o non si vuole incorrere nell’overhead. Ecco un approccio:

 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; } 

So che questo è stato risposto diverse volte, ma volevo aggiungere qualche informazione in più su questo argomento. Per la documentazione di Bluebird, è necessario utilizzare l”uso’ per la pulizia delle connessioni e prevenire perdite di memoria. Gestione delle risorse in Bluebird

Ho cercato dappertutto come fare correttamente e le informazioni erano scarse, quindi ho pensato di condividere ciò che ho trovato dopo molte prove ed errori. I dati che ho usato qui sotto (ristoranti) provengono dai dati di esempio di MongoDB. Puoi ottenerlo qui: Dati di importazione MongoDB

 // 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); } ); 

Spero che questo aiuti qualcun altro che vuole fare le cose con il libro di Bluebird.

La versione 1.4.9 di mongodb dovrebbe ora essere facilmente promettibile in quanto tale:

 Promise.promisifyAll(mongo.Cursor.prototype); 

Vedi https://github.com/mongodb/node-mongodb-native/pull/1201 per maggiori dettagli.

Stiamo utilizzando il seguente driver in produzione da un po ‘di tempo. È essenzialmente un wrapper di promise sul driver node.js nativo. Aggiunge anche alcune funzioni di supporto aggiuntive.

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