2013-12-18 5 views
1

Я пытаюсь создать модуль, который подключается к моей базе данных (couchDB с помощью Cradle). В итоге модуль экспортирует переменную 'db'.Asynchrously загрузить модуль NPM

Вот код:

var cradle = require('cradle'), 
config = require('./config.js'); 

var db = new(cradle.Connection)(config.couchURL, config.couchPort, { 
    auth: { 
     username: config.couchUsername, 
     password: config.couchPassword 
    }, 
    cache: true, 
    retries: 3, 
    retryTimeout: 30 * 1000 
}).database('goblin'); //database name 



//Check if DB exists 
db.exists(function (err, exists) { 
    if (err && exists) { 
     console.log("There has been an error finding your CouchDB. Please make sure you have it installed and properly pointed to in '/lib/config.js'."); 
     console.log(err); 
     process.exit(); 
    } else if (!exists) { 
     db.create(); 
     console.log("Welcome! New database created."); 
    } else { 
     console.log("Talking to CouchDB at " + config.couchURL + " on port " + config.couchPort); 
    } 

}); 

module.exports = db; 

Проблема заключается в том, что db.exists называют это асинхронная, и если он не существует, я думаю, что переменная экспортирует переменную прежде, чем это будет сделано, производя остальное система.

Он включается в странице выполненного узла обычного способом:

var db = require('./couchdb.js'); 

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

Для справки: Вы можете увидеть все приложение прямо здесь (https://github.com/maned/goblin), а также указанную здесь ошибку (https://github.com/maned/goblin/issues/36).

ответ

2

Обнимать асинхронный стиль. Вместо экспорта db из модуля, экспортировать функцию асинхронной так:

module.exports = { 
    getDb: function(callback) { 
    db.exists(function(err, exists) { 
     if (exists && !err) {callback(db);} else { /* complain */ } 
    }); 
    } 
}; 

Теперь приложение может просто require('mymodule').getDb(appReady) где appReady принимает db объект, который, как известно, действует и годным к употреблению.

+0

Это хорошее решение! Я пытаюсь сейчас, но имею некоторые проблемы с объектом db. Будет ли обновлять этот поток! Я старался изо всех сил избегать наличия таких вызовов (много кода переходит в обратный вызов), но, возможно, это лучший способ сделать это. – streetlight

+0

Вы можете «отчислить» части вашего обратного вызова, которые никогда не меняются на другие функции или, если вы чувствуете себя взволнованными, в закрытие. Таким образом, только очень маленькие функции динамически создаются с каждым вызовом вашего обработчика событий. – wberry

Смежные вопросы