我正在尝试节点 0.12 中的一些和声功能,特别是尝试新的生成器功能。我正在使用 co(v4),bluebird 和 express(v4),如下所示:
// ...
var fs = bluebird.promisifyAll(require('fs'));
// ...
app.post('/test', co.wrap(function* (req, res, next) {
var contents = yield fs.readFileAsync('/etc/hosts', 'utf8');
return res.send(contents);
}));
// ...
根据其文档,co.wrap 返回一个正常的函数,该函数从给定的生成器函数返回一个承诺。
到目前为止,这是正常工作,但我不确定的是,如果 a)我通过不“等待”返回的承诺的结果而泄漏内存,b)如果我可能会丢失在我的生成器函数中抛出的异常,或者它使用的模块之一。
这是一个好方法吗?你看到它有什么问题吗?。
你的方法的问题是,如果你的生成器函数会抛出一些异常,它不会传递给下一个中间件。所以你会失去它。你可以使用 bluebird 的Promise.coroutine
函数来实现你自己的简单co
包装器,它将在 express 中运行良好:
// module: ../helpers/co.js
var Promise = require('bluebird');
var co = Promise.coroutine;
module.exports = function(gen) {
var coGen = co(gen);
function handle_error(err, req, res, next) {
return coGen.apply(this, arguments).catch(next);
}
function handle_request(req, res, next) {
return coGen.apply(this, arguments).catch(next);
}
return gen.length > 3 ? handle_error : handle_request;
};
UPD:我已经改变了实现一点。现在它考虑了传递到生成器中的数字或参数:如果 & gt;3 那么将使用错误处理程序,否则-请求处理程序。这对 express 很重要(查看源代码here和here)
现在您可以在代码中使用它:
// module: your/router.js
// ...
var co = require('../helpers/co');
var fs = bluebird.promisifyAll(require('fs'));
// ...
app.post('/test', co(function* (req, res, next) {
var contents = yield fs.readFileAsync('/etc/hosts', 'utf8');
return res.send(contents);
}));
// ...
UPD这是版本为 & lt;= 4.x 的 express 的解决方案。最有可能的 express 5.xwill support promises,因此您可以使用 bluebird 的Promis.coroutine
而没有任何花哨的包装:
// module: your/router.js
// ...
var fs = bluebird.promisifyAll(require('fs'));
var co = bluebird.coroutine;
// ...
app.post('/test', co(function*(req, res, next) {
var contents = yield fs.readFileAsync('/etc/hosts', 'utf8');
return res.send(contents);
}));
// ...
本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处
评论列表(20条)