Подтвердить что ты не робот

Как использовать MongoDB с promises в Node.js?

Я пытался узнать, как использовать MongoDB с Node.js, и в документах кажется, что предложенный способ - использовать обратные вызовы. Теперь я знаю, что это всего лишь вопрос предпочтения, но я действительно предпочитаю использовать promises.

Проблема в том, что я не нашел, как использовать их с MongoDB. Действительно, я пробовал следующее:

var MongoClient = require('mongodb').MongoClient;

var url = 'mongodb://localhost:27017/example';

MongoClient.connect(url).then(function (err, db) {
    console.log(db);
});

И результат undefined. В этом случае кажется, что это не способ сделать это.

Есть ли способ использовать mongo db внутри Node с promises вместо обратных вызовов?

4b9b3361

Ответ 1

Ваш подход почти правильный, всего лишь небольшая ошибка в вашем аргументе

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

Поскольку ни один из вышеперечисленных ответов не упоминает, как это сделать без bluebird или q или любой другой причудливой библиотеки, позвольте мне добавить мои 2 цента на этом.

Вот как вы делаете вставку с родным 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;

Я определил свой метод open() как возвращающий обещание. Чтобы выполнить вставку, вот мой фрагмент кода ниже

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

Надеюсь, что это поможет. Если у вас есть предложения, чтобы сделать это лучше, дайте мне знать, поскольку я готов улучшить себя:)

Ответ 3

Это общий ответ для Как использовать MongoDB с обещаниями в Node.js?

mongodb вернет обещание, если параметр обратного вызова пропущен

Перед переходом на Обещание

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

После преобразования в Обещание

//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 вам нужно обработать несколько запросов

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

Вы также можете сделать async/await

async function main(){
 let client, db;
 try{
    client = await MongoClient.connect(mongoUrl, {useNewUrlParser: true});
    db = client.db(dbName);
    let dCollection = db.collection('collectionName');
    let result = await dCollection.find();   
    // let result = await dCollection.countDocuments();
    // your other codes ....
    return result.toArray();
 }
 catch(err){ console.error(err); } // catch any mongo error here
 finally{ client.close(); } // make sure to close your connection after
}

Ответ 5

ПРЕДУПРЕЖДЕНИЕ Изменить:

Как отметил Джон Кулвинер, этот ответ устарел. Используйте драйвер, он поставляется с promises OOTB.


Если вы решите использовать bluebird в качестве библиотеки обещаний, вы можете использовать функцию bluebirds promisifyAll() на 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);
});

Ответ 6

Рабочее решение с версией MongoDB > 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)
    })

Ответ 7

Вы можете использовать альтернативный пакет, например mongodb-promise или пообещать API пакета mongodb вручную, создав свой собственный promises вокруг него или через пакет служебных обещаний, например bluebird.promisify

Ответ 8

Не похоже, что метод подключения имеет определенный интерфейс обещания

http://mongodb.github.io/node-mongodb-native/2.1/tutorials/connect/

вы всегда можете реализовать его самостоятельно в библиотеке соединителей Mongodb, но это, вероятно, больше связано с тем, что вы ищете.

Если вам действительно нужно работать с promises, вы всегда можете использовать обещание ES6 polyfill:

https://github.com/stefanpenner/es6-promise

и заверните код подключения. Что-то вроде

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

Ответ 9

Вам нужно создать обещание, которое соединяется с Mongo.

Затем определите свою функцию, которая использует это обещание: myPromise.then(...).

Например:

function getFromMongo(cb) {
    connectingDb.then(function(db) {

       db.collection(coll).find().toArray(function (err,result){
           cb(result);
       });

    });
}

вот полный код:

http://jsfiddle.net/t5hdjejg/