Node.js: использование промисов с MongoDb

Я начал использовать пакет Q Promise в простом приложении node.js. Поэтому меня интересует, как я могу закрыть соединение с базой данных после завершения всей последовательности обещаний.

Пример:

var toDbConnectionString = function(dbSettings) {
    return "mongodb://" +
        dbSettings.user + ":" +
        dbSettings.password + "@" +
        dbSettings.url;
};

var connectionString = toDbConnectionString(dbSettings);

Q.nfcall(
    MongoClient.connect,
    toDbConnectionString(dbSettings))
.then(function(db) {
    return Q.ninvoke(db, "collectionNames");
})
.then(function(collections) {
    console.log(collections);
})
.catch(function() {
    console.log(arguments);
});

Я хочу закрыть соединение после отображения имен коллекций, но в этой анонимной функции нет контекста базы данных.

Есть ли способ обрабатывать такие случаи с помощью шаблона обещания?


person shadeglare    schedule 01.10.2013    source источник
comment
Почему бы не зафиксировать значение db и не использовать его на последнем шаге?   -  person WiredPrairie    schedule 01.10.2013
comment
Я могу использовать это решение, но, возможно, есть более элегантный способ.   -  person shadeglare    schedule 01.10.2013
comment
Поскольку обычно у вас должно быть только одно подключение к БД для каждого экземпляра узла, это, безусловно, ожидаемо. Кроме того, вы должны учитывать, что обычно вам нужно будет использовать его в других местах вашего кода, поэтому он должен быть доступен. Например, что, если вы захотите позже подсчитать количество документов в коллекции (используя их имена)?   -  person WiredPrairie    schedule 01.10.2013
comment
Вас может заинтересовать mongojs, который предлагает гораздо более удобный API и автоматическое подключение для вас и mongod, который основан на этом, предоставляя промисы вместо обратных вызовов в качестве API.   -  person ForbesLindesay    schedule 08.10.2013


Ответы (2)


Вы можете произвольно вкладывать then-обратные вызовы. Да, это приближает к пирамиде гибели, но это единственный способ сохранить аргументы в рамках. В твоем случае:

Q.nfcall(
    MongoClient.connect,
    toDbConnectionString(dbSettings))
.then(function(db) {
    return Q.ninvoke(db, "collectionNames")
    .then(function(collections) {
        console.log(collections);
    }).finally(function() {
        db.close();
    });
})
.catch(console.log.bind(console));

Однако обратите внимание, что вы обычно не подключались и не закрывались слишком часто.

person Bergi    schedule 03.10.2013

Если вы не хотите вкладываться (я, конечно, не хочу...), вы можете просто сделать так:

var toDbConnectionString = function(dbSettings) {
    return "mongodb://" +
        dbSettings.user + ":" +
        dbSettings.password + "@" +
        dbSettings.url;
};

var connectionString = toDbConnectionString(dbSettings);
var db;

Q.nfcall(
    MongoClient.connect,
    toDbConnectionString(dbSettings))
.then(function(_db) {
    db = _db;
    return Q.ninvoke(db, "collectionNames");
})
.then(function(collections) {
    console.log(collections);
})
.catch(function() {
    console.log(arguments);
})
.finally(function() {
    if (db) db.close();
});
person Esailija    schedule 07.10.2013