javascript - 与 bluebird 和 co 一起快速生成生成器功能

标签 javascript node.js promise generator ecmascript-6

我正在尝试 Node 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 返回一个普通函数,该函数返回给定生成器函数的 promise 。

到目前为止一切正常,但我不确定是否 a) 我没有“等待”返回的 promise 的结果而导致内存泄漏 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:我对实现做了一点改动。现在它考虑了传递给生成器的数字或参数:如果 > 3 则将使用错误处理程序,否则 - 请求处理程序。这对 express 很重要(查看源代码 herehere )

现在您可以在代码中使用它了:

// 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 这是 express 版本 <= 4.x 的解决方案。最有可能表达 5.x will 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);
}));
// ...

关于javascript - 与 bluebird 和 co 一起快速生成生成器功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29186246/

相关文章:

javascript - jqgrid自定义ajax请求

javascript - 根据对象的属性删除数组的对象

javascript - 我可以在不创建延迟的情况下报告 Q promise 进度吗?

javascript - 如何在 Node.js 中使用 async/await 编写依赖项

javascript - promise 排队?

javascript - ng-change 不适用于单选按钮

javascript - 将 JavaScript 函数作为参数传递

node.js - 如何在 Windows 上使用 Cygwin 将 coffee-script 模块包含在 Node 中

node.js - 使用 Hapi.JS Joi 模块在 Express.JS 应用程序中验证和清理输入之间的区别?

javascript - Google Calendar API - 获取用户的所有 session 邀请