可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I've been trying to discover how to use MongoDB with Node.js and in the docs it seems the suggested way is to use callbacks. Now, I know that it is just a matter of preference, but I really prefer using promises.
The problem is that I didn't find how to use them with MongoDB. Indeed, I've tried the following:
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/example';
MongoClient.connect(url).then(function (err, db) {
console.log(db);
});
And the result is undefined
. In that case it seems this is not the way to do so.
Is there any way to use mongo db inside Node with promises instead of callbacks?
回答1:
Your approach is almost correct, just a tiny mistake in your argument
var MongoClient = require('mongodb').MongoClient
var url = 'mongodb://localhost:27017/example'
MongoClient.connect(url)
.then(function (db) { // <- db as first argument
console.log(db)
})
.catch(function (err) {})
回答2:
Since none of the answers above mention how to do this without bluebird or q or any other fancy library, let me add my 2 cents on this.
Here's how you do an insert with native ES6 promises
'use strict';
const
constants = require('../core/constants'),
mongoClient = require('mongodb').MongoClient;
function open(){
// Connection URL. This is where your mongodb server is running.
let url = constants.MONGODB_URI;
return new Promise((resolve, reject)=>{
// Use connect method to connect to the Server
mongoClient.connect(url, (err, db) => {
if (err) {
reject(err);
} else {
resolve(db);
}
});
});
}
function close(db){
//Close connection
if(db){
db.close();
}
}
let db = {
open : open,
close: close
}
module.exports = db;
I defined my open() method as the one returning a promise. To perform an insert, here is my code snippet below
function insert(object){
let database = null;
zenodb.open()
.then((db)=>{
database = db;
return db.collection('users')
})
.then((users)=>{
return users.insert(object)
})
.then((result)=>{
console.log(result);
database.close();
})
.catch((err)=>{
console.error(err)
})
}
insert({name: 'Gary Oblanka', age: 22});
Hope that helps. If you have any suggestions to make this better, do let me know as I am willing to improve myself :)
回答3:
This is a General answer for How to use MongoDB with promises in Node.js?
mongodb will return a promise if the callback parameter is omitted
Before converting to Promise
var MongoClient = require('mongodb').MongoClient,
dbUrl = 'mongodb://db1.example.net:27017';
MongoClient.connect(dbUrl,function (err, db) {
if (err) throw err
else{
db.collection("users").findOne({},function(err, data) {
console.log(data)
});
}
})
After converting to Promise
//converted
MongoClient.connect(dbUrl).then(function (db) {
//converted
db.collection("users").findOne({}).then(function(data) {
console.log(data)
}).catch(function (err) {//failure callback
console.log(err)
});
}).catch(function (err) {})
Incase you need to handle multiple request, [ Requires bluebird module ]
var Promise = require('bluebird');
MongoClient.connect(dbUrl).then(function (db) {
/*---------------------------------------------------------------*/
var allDbRequest = [];
allDbRequest.push(db.collection("users").findOne({}));
allDbRequest.push(db.collection("location").findOne({}));
Promise.all(allDbRequest).then(function (results) {
console.log(results);//result will be array which contains each promise response
}).catch(function (err) {
console.log(err)//failure callback(if any one request got rejected)
});
/*---------------------------------------------------------------*/
}).catch(function (err) {})
回答4:
WARNING Edit:
As John Culviner noted, this answer is deprecated. Use the driver, it comes with promises OOTB.
If you choose to use bluebird as a promise library, you can use bluebirds promisifyAll()
function on MongoClient:
var Promise = require('bluebird');
var MongoClient = Promise.promisifyAll(require('mongodb').MongoClient);
var url = 'mongodb://localhost:27017/example';
MongoClient.connectAsync(url).then(function (db) {
console.log(db);
}).catch(function(err){
//handle error
console.log(err);
});
回答5:
Working solution with MongoDB version > 3.0
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
open = (url) => {
return new Promise((resolve,reject) => {
MongoClient.connect(url, (err,client) => { //Use "client" insted of "db" in the new MongoDB version
if (err) {
reject(err)
} else {
resolve({
client
});
};
});
});
};
create = (client) => {
return new Promise((resolve,reject) => {
db = client.db("myFirstCollection"); //Get the "db" variable from "client"
db.collection("myFirstCollection").insertOne({
name: 'firstObjectName',
location: 'London'
}, (err,result)=> {
if(err){reject(err)}
else {
resolve({
id: result.ops[0]._id, //Add more variables if you want
client
});
}
});
});
};
close = (client) => {
return new Promise((resolve,reject) => {
resolve(client.close());
})
};
open(url)
.then((c) => {
clientvar = c.client;
return create(clientvar)
}).then((i) => {
idvar= i.id;
console.log('New Object ID:',idvar) // Print the ID of the newly created object
cvar = i.client
return close(cvar)
}).catch((err) => {
console.log(err)
})
回答6:
You can either use an alternative package, such as mongodb-promise
or promisify the mongodb
package API manually by building your own promises around it or via a promise utility package like bluebird.promisify
回答7:
It doesn't look like the connect method has a promise interface defined
http://mongodb.github.io/node-mongodb-native/2.1/tutorials/connect/
you could always implement it yourself in the Mongodb connector library, but that's probably more involved than you are looking for.
If you really need to work with promises, you can always use the ES6 promise polyfill:
https://github.com/stefanpenner/es6-promise
and wrap your connection code with that. Something like
var MongoClient = require('mongodb').MongoClient;
var Promise = require('es6-promise').Promise;
var url = 'mongodb://localhost:27017/example';
var promise = new Promise(function(resolve, reject){
MongoClient.connect(url, function (err, db) {
if(err) reject(err);
resolve(db);
});
});
promise.then(<resolution code>);
回答8:
You need to create a promise that connects to Mongo.
Then, define your function that uses this promise: myPromise.then(...)
.
For example:
function getFromMongo(cb) {
connectingDb.then(function(db) {
db.collection(coll).find().toArray(function (err,result){
cb(result);
});
});
}
here is the full code:
http://jsfiddle.net/t5hdjejg/