Node.js生成器

时间:2015-09-18 21:11:20

标签: javascript node.js generator

我不确定如何构建Javascript生成器代码以使其正确执行。

var req = yield http.request(options, callback);

我已经有了emailHtml()函数从本地sqlite数据库中获取数据,并通过带有http.request的POST传递数据但是无法弄清楚如何构造我的代码以使emailHtml()函数返回回调的最终字符串。

我是否还需要将回调作为生成器功能?我已经尝试了sec_a = np.roll(mtrx, -1, axis=0) sec_b = np.roll(mtrx, -1, axis=1) result = (mtrx + sec_a + sec_b) / 3 ,但由于这会停止请求,因此永远不会写入POST数据,并且请求永远不会在以下两行中完成。

如果生成器不是正确的方法,我还有哪些其他选择?

2 个答案:

答案 0 :(得分:3)

您需要将HTTP调用转换为可以产生的效果。现在写起来很混乱,所以有时间介绍一些其他工具 - 特别是承诺。既然你正在使用Koa,它在引擎盖下使用了一个名为co的库,promises可能是最简单的方法。我倾向于使用名为Bluebird的库来实现我的承诺,还有其他选择。

所以基本上你想要这样的东西:

var http = require('http');
var Promise = require('bluebird');

emails.send = function *(next) {
    // Pull the HTML for email to be sent from another local server
    mailOptions['html'] = yield* emailHtml();
    ...
};

function makeHttpRequest(options, data) {
    // Note we're returning a promise here
    return new Promise(function (resolve, reject) {
        var req = http.request(options, callback);
        req.write(JSON.stringify(data));
        req.end();

        function callback(response) {
            var str = '';
            response.on('data', function (chunk) {
                str += chunk;
            });
            response.on('end', function (chunk) {
                // -- Resolve promise to complete the request
                resolve(str);
            });
        }
    });
}

function* emailHtml() {
    // Get the data from the database -- ends up using node-sqlite
    var data = yield mea.getMeasurements();

    // Callback function to deal with http request below
    function callback(response) {
        var str = '';

        response.on('data', function(chunk) {
            str += chunk;
        });
        response.on('end', function(chunk) {
            return str;
        });
    }

    // Make a request to the other server to get it's HTML
    var str = yield makeHttpRequest(options, data);

    // do whatever you want with the result
    return ??????;
}

这会将一个http内容包装在一个promise对象中,你在外层的生成器运行器知道如何等待完成。

还有其他方法可以做到这一点,以及本地包装这些东西的库(如co-request),但这是基本的想法。

答案 1 :(得分:1)

加上克里斯'回答,这里是我现在正在使用的代码的清理版本:

var http = require('http');

emails.send = function *(next) {
    // Pull the HTML for email to be sent from another local server
    mailOptions['html'] = yield* emailHtml();
};

function makeHttpRequest(options, data) {
    // Note we're returning a promise here
    return new Promise(function (resolve, reject) {
        var req = http.request(options, callback);
        req.write(JSON.stringify(data));
        req.end();

        function callback(response) {
            var str = '';
            response.on('data', function (chunk) {
                str += chunk;
            });
            response.on('end', function (chunk) {
                // -- Resolve promise to complete the request
                resolve(str);
            });
        }
    });
}

function* emailHtml() {
    // Get the data from the database -- ends up using node-sqlite
    var data = yield mea.getMeasurements()

    // Make a request to the other server to get it's HTML
    return yield makeHttpRequest(options, data);

}
当您使用--harmony标志时,

Prom已经内置到Node v0.12.7中,因此不需要额外的库