我一直在试图弄清楚如何使用node-fiber来使我的数据库代码在node.js中变得不那么混乱,但我无法让它工作。我将代码简化为最低测试用例:
var Future = require('fibers/future');
var pg=require('pg');
var connstr = "pg://not_the_real_user:or_password@localhost/db";
var pconnect = Future.wrap(pg.connect);
Fiber(function() {
var client = pconnect(connstr).wait();
console.log("called function");
}).run();
如果我保持原样,我会收到以下错误:
pgfuture.js:10
}).run();
^
TypeError: undefined is not a function
at Object.PG.connect.pools.(anonymous function).genericPool.Pool.create (/home/erik/code/treehouse-node/node_modules/pg/lib/index.js:49:20)
at dispense (/home/erik/code/treehouse-node/node_modules/pg/node_modules/generic-pool/lib/generic-pool.js:223:17)
at Object.exports.Pool.me.acquire (/home/erik/code/treehouse-node/node_modules/pg/node_modules/generic-pool/lib/generic-pool.js:267:5)
at PG.connect (/home/erik/code/treehouse-node/node_modules/pg/lib/index.js:75:15)
at Future.wrap (/home/erik/code/treehouse-node/node_modules/fibers/future.js:30:6)
at /home/erik/code/treehouse-node/pgfuture.js:8:18
但是,如果我注释掉调用pconnect的行,我会在控制台上收到“被调用函数”消息并且没有错误。 github页面上的示例具有几乎相同的结构,并且它在我的系统上正常工作,但我对这里的错误感到难过。
编辑:其他详细信息
我已经设法让代码以一种似乎无关的两种不同方式运行,但两者都有相同的行为。函数完成后,节点只挂起,我必须用ctrl-c杀掉它。以下是我为完成这一结果所做的两件事:
1)在匿名函数中包装pg.connect,然后使用Future包装THAT:
pconnect = Future.wrap(function(err,cb){pg.connect(err,cb);});
2)这个是一个真正的谜,但似乎有相同的结果。在光纤内部,我只是在调用pconnect之前直接调用pg.connect,一切似乎都解决了。
// add this line before call to pconnect
pg.connect(connstr, function(e,c){console.log("connected.");});
// and now the original call to pconnect
var client = pconnect(connstr).wait();
我可以想象一种情况,其中(1)是有意义的,例如,如果pg.connect函数有其他可选参数,它们以某种方式干扰了Future.wrap调用的预期布局。另一种可能性是对象超出范围,并且在实际调用pconnect时未定义“this”引用。我不知道为什么(2)有任何影响。
编辑:部分回答
好的,所以我至少回答了部分问题。关于对象范围的想法证明是正确的,并且通过使用bind()函数,我能够消除额外的回调包装层:
var pconnect = Future.wrap(pg.connect.bind(pg));
虽然原因不明,但仍然在执行结束时挂起。
答案 0 :(得分:1)
您是否在执行结束时与数据库断开连接?
如果没有,它会阻止node.js程序退出。
答案 1 :(得分:0)
添加我自己的另一个泄密代码。
@Almad我在这里与提供的回调断开连接,但仍然挂起:
var future = Future.task(function() {
var ret = Future.wrap (pg.connect.bind(pg), "array") (conString).wait ();
ret[1]();
}).detach();