发电机function与蓝鸟和coexpression

我正在尝试使用节点0.12中的一些和声function,特别是尝试使用新的生成器function。 我正在用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返回一个正常的函数,它返回给定生成器函数的promise。

到目前为止,这是工作正常,但我不知道的是,如果a)我通过不等待返回的承诺的结果泄漏内存和b)如果我可能会失去一个exception抛出我的生成器函数,或一它使用的模块。

这是一个好方法吗? 你看到有什么不对吗?

你的方法的问题是,如果你的生成器函数会抛出一些exception,它不会被传递到下一个中​​间件。 所以你会失去它。 你可以使用蓝鸟的Promise.coroutine函数来实现你自己的简单的co包装,这将是快速运行:

 // 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 :我已经改变了一点。 现在它考虑到传递到生成器的数量或参数:if> 3,那么将使用error handling程序,否则请求处理程序。 对于快递来说很重要(查看这里和这里的源代码)

现在你可以在你的代码中使用它:

 // 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这是使用版本<= 4.x的快速解决scheme。 5.x很可能会支持承诺 ,所以你可以使用蓝鸟的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); })); // ...