Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Node.js生成器_Javascript_Node.js_Generator - Fatal编程技术网

Javascript Node.js生成器

Javascript Node.js生成器,javascript,node.js,generator,Javascript,Node.js,Generator,我不确定如何构造Javascript生成器代码,使其能够正确执行 ... 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* emailHtml() {

我不确定如何构造Javascript生成器代码,使其能够正确执行

...

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* 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 req = http.request(options, callback);
    // Post the data from this server's database connection to the other server to be processed and sent back
    req.write(JSON.stringify(data));
    req.end();

    return ??????;

}
...
我已经有了emailHtml()函数,该函数从本地sqlite数据库生成数据,并通过POST将该数据与http.request一起传递,但我不知道如何构造代码,使emailHtml()函数返回回调的最终字符串

我是否需要使回调函数也成为生成器函数?我尝试了
var req=yield http.request(选项,回调)
但是由于这停止了请求,POST数据永远不会被写入,请求也永远不会在下面两行中完成


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

您需要将HTTP调用转换为可以实现的功能。正如目前所写的,它很混乱,所以是时候使用其他一些工具了——特别是承诺。因为你使用的膝关节炎,在引擎盖下使用一个叫做CO的库,承诺可能是最简单的方法。我倾向于使用名为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)以本机方式包装这些内容,但这是基本思想。

再加上Chris的回答,下面是我现在使用的代码的清理版本:

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标志时,承诺已经内置到节点v0.12.7中,因此不需要额外的库

生成器还不能等待异步代码。这里的答案是将http.request调用转换为生成器,以便生成它。如何实现这一点的具体细节在很大程度上取决于您如何运行发电机。你在用图书馆吗?哪一个?什么叫emails.send?感谢Chris的帮助--“http”库是节点v0.12.7附带的标准库。生成KOA.JS路由文件的生成器列表中的另一个生成器正在调用Email。除了重写标准http库,还有其他选择吗?我试图遵循代码,但无法使与代码的关联正确地工作,就像一个符咒——感谢您澄清了我的承诺与生成器混淆