Я использую модуль узла pg
postgres для взаимодействия с моей базой данных. Код работает без проблем, когда я использую событийный API pg
. Ниже приведен пример кода:
Миграция.js
exports.up = function(logger){
var pg = require("pg")
, connectionString = //process.env.CONNECTIONSTRING
, client = new pg.Client(connectionString);
client.connect();
var cmd = "CREATE TABLE users( "
+ "id SERIAL NOT NULL, "
+ "firstName VARCHAR(50) NOT NULL, "
+ "lastName VARCHAR(50) NOT NULL, "
+ "CONSTRAINT pk_userid PRIMARY KEY (id) "
+ ")";
var query = client.query(cmd);
query.on("end", function(){
client.end();
logger.log("complete");
});
};
Я использую commander.js, чтобы написать утилиту командной строки для этого сценария миграции; однако неблокирующий вызов фрагмента pg
освобождает сценарий интерфейса командной строки для завершения до того, как будут выполнены обновления базы данных. Ниже приведен пример фрагмента командной строки:
Мой клитор
var program = require('commander');
program
.version('1.0.2');
program
.command("up")
.description("Migrates up")
.action(function(){
require("../src/migration").up();
});
// Additional code removed for brevity
Есть ли способ изменить сценарий миграции (или приложения commander.js
), чтобы гарантировать, что функция миграции up()
завершится до завершения моего сценария cli? Я пытался использовать обратные вызовы, но, похоже, это не работает.
ОБНОВЛЕНИЕ Еще один пример, иллюстрирующий этот момент. Ниже приведен модульный тест (написанный с помощью mocha
), касающийся этой проблемы.
Up-test.js
describe("feature", function(){
it("should finish", function(){
var logger = {};
var finished = false;
logger.log = function(){finished = true;};
var migration = require("../src/migration.js");
migration.up(logger);
assert(finished, "function didn't finish"); // finished is false when this gets called.
});
});
pg
, передавая обратный вызов в конце, а также добавляя обратный вызов в функциюup()
и вызывая ее послеclient.end()
, и в обоих случаях код, вызывающий функциюup()
, продолжается, проходит мимо вызова и, в конечном счете, заканчивается раньше, чемup()
. - person JamesEggers   schedule 07.07.2012assert(finished);
должен быть внутри вашей функцииlogger.log
или внутри чего-то, что не будет выполнено немедленно. Mocha предоставляет вам обратный вызов для асинхронных тестов, который вам также придется использовать:it("should finish", function (completedCallback) { });
см. visionmedia .github.com/mocha/#асинхронный-код - person Andrew Dunkman   schedule 07.07.2012