Promise and nodejs driver MongoDB

I would like to promise with the MongoDB driver. I wrote the following code:

var TaskBroker = function () { this.queueName = 'task_queue'; this.rabbit = {}; this.mongo = {}; }; TaskBroker.prototype.connectRabbit = function() { var self = this; return amqp.connect('amqp://localhost') .then(function(connection) { self.rabbit.connection = connection; return connection.createChannel() }) .then(function(channel) { self.rabbit.channel = channel; return channel.assertQueue(self.queueName, {durable: true}); }) }; TaskBroker.prototype.connectMongo = function() { console.log('Connect Mongo'); var self = this; var defer = q.defer(); MongoClient.connect('mongodb://127.0.0.1:27017/test', {}, defer.makeNodeResolver()); return defer.promise.then(function(db) { self.mongo.db = db; console.log('hello'); return 42; }); }; TaskBroker.prototype.connect = function () { var self = this; return this.connectRabbit() .then(self.connectMongo); }; 

You have an idea why I don't have hello output when I call the connect method:

 taskBroker.connect() .then(function(result) { console.log('Disconnected'); taskBroker.disconnect(); }); 
+6
source share
3 answers

A manually promising API is dangerous, I suggest something like:

 TaskBroker.prototype._connectMongo = Q.nfcall(MongoClient.connect, 'mongodb://127.0.0.1:27017/test', {}); TaskBroker.prototype.connectMongo = function(){ return this._connectMongo().then(function(db){ console.log("Hello"); // self.stuff... return 42; }).catch(function(e){ console.err("connection error",e); // log the connection error, or handler err throw e; // don't mark as handled, propagate the error. }); }; 

With Bluebird promises, it looks something like this:

 var MongoClient = Promise.promisifyAll(require("mongodb").MongoClient); TaskBroker.prototype.connectMongo = function(){ return MongoClient.connectAsync().then(... // Bluebird will automatically track unhandled errors }; 
+9
source

v2.0.36 driver node mongodb introduced first-class support for promises.

Here is an example from official docs:

 // A simple query showing skip and limit using a Promise. var MongoClient = require('mongodb').MongoClient, test = require('assert'); MongoClient.connect('mongodb://localhost:27017/test', function(err, db) { // Create a collection we want to drop later var collection = db.collection('simple_limit_skip_query_with_promise'); // Insert a bunch of documents for the testing collection.insertMany([{a:1, b:1}, {a:2, b:2}, {a:3, b:3}], {w:1}).then(function(result) { // Peform a simple find and return all the documents collection.find({}) .skip(1).limit(1).project({b:1}).toArray().then(function(docs) { test.equal(1, docs.length); test.equal(null, docs[0].a); test.equal(2, docs[0].b); db.close(); }); }); }); 

The es6-promise library is used by default, but you can override this when creating a database connection:

 var MongoClient = require('mongodb').MongoClient; MongoClient.connect('mongodb://localhost:27017/test', { promiseLibrary: require('bluebird') }, function(err, db) { // ... 
+7
source

Mongodb

To process the mongodb driver, I suggest using then-mongo (disclaimer: I wrote it). This is equivalent to mongojs , with the exception of promises instead of callbacks. It also allows you to consider the "connect" operation as synchronous, immediately returning an object with which you can interact, and just wait for the connection inside. It's very nice that it complies with the official mongodb documentation, so you can just use this documentation to figure out how to use it.

General case

In general, using an API that does not return a promise, and getting what needs to be done should be done using the Promise constructor. eg.

 function readFile(filename, enc){ return new Promise(function (fulfill, reject){ fs.readFile(filename, enc, function (err, res){ if (err) reject(err); else fulfill(res); }); }); } 

If you use Q, you should:

 function readFile(filename, enc){ return q.promise(function (fulfill, reject){ fs.readFile(filename, enc, function (err, res){ if (err) reject(err); else fulfill(res); }); }); } 

Helper Methods

Many of the libraries included with Q provide special helper methods for adapting node.js style callback methods to return promises. eg.

 var readFile = q.denodeify(fs.readFile); 

or promise :

 var readFile = Promise.denodeify(fs.readFile); 

If you need more information on how to create and use Promise objects in general (and not Q), I would suggest you check out https://www.promisejs.org/ (diclaimer: I wrote this).

+6
source

All Articles