Node.js – 确保一个非阻塞呼叫结束

我正在使用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围绕此迁移脚本编写命令行实用程序; 然而, pg片段的非阻塞调用释放了命令行界面脚本,在数据库更新完成之前完成。 下面是一个示例指挥官片段:

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脚本之前完成? 我曾尝试使用callback,但似乎不工作。

更新另一个例子来说明这一点。 以下是关于这个问题的unit testing(用mocha书写)。

向上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. }); }); 

看起来你的原始脚本有一个痛苦点周围program.action(function () {});

 program .command("up") .description("Migrates up") .action(function(){ require("../src/migration").up(); // nothing preventing this function from exiting immediately }); 

我在commander.js docs中search了一下,找不到任何有关向.action()程序提供callback的信息。 如果我正在写它,代码将如下所示:

 program .command("up") .description("Migrates up") .action(function (completedCallback) { require("../src/migration").up(function () { // migration is complete completedCallback(); }); }); 

虽然你的postgre相关的脚本看起来不错。 有些不相关的注释可能是require("../src/migration").up(); 返回一个require("events").EventEmitter的实例require("events").EventEmitter发出你想要查看的事件,而不是使用一个loggervariables。 但是,这只是偏好。

尝试设置定时器(http://nodejs.org/api/timers.html)。 我们在Azure CLI工具中执行此操作,以便在执行长时间运行操作时运行微调器。

您可以在这里钻取代码,看看我们是如何做到的: https : //github.com/WindowsAzure/azure-sdk-for-node/blob/master/lib/cli/cli.js 。 searchprogress()函数。