【发布时间】:2012-07-07 08:08:51
【问题描述】:
我正在使用pg postgres 节点模块与我的数据库进行交互。当我使用 pg 的事件 API 时,代码可以正常工作。下面是代码示例:
Migration.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 围绕此迁移脚本编写命令行实用程序;但是,pgsn-p 的非阻塞调用正在释放命令行界面脚本,以便在数据库更新完成之前完成。下面是一个示例指挥官 sn-p:
MyCliTool
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.
});
});
【问题讨论】:
-
您是否尝试过将回调传递给 client.query() 而不是使用 query.on()?
-
我试过
pg的回调语法,在最后传入一个回调,并在up()函数中添加一个回调并在client.end()之后调用,在这两种情况下,调用up()函数的代码继续执行,通过调用并最终在up()之前完成。 -
这就是异步代码的运作方式。如果您想“等待” up 继续,您需要让 up() 调用回调,并且只从该回调继续执行。
-
你的 up-test.js 看起来有点错误:
assert(finished);应该在你的logger.log函数内,或者在不会立即执行的东西内。 Mocha 为您提供了一个异步测试回调,您也必须使用它:it("should finish", function (completedCallback) { });请参阅visionmedia.github.com/mocha/#asynchronous-code
标签: postgresql node.js javascript-events flow-control