javascript - Node.js 生成器

标签 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() {
    // 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 数据库生成数据并使用 http.request 通过 POST 传递该数据,但无法弄清楚如何构建我的代码以使 emailHtml() 函数返回回调的最终字符串。

我还需要将回调函数设为生成器函数吗?我试过 var req = yield http.request(options, callback); 但由于请求停止,POST 数据永远不会写入,请求也永远不会在以下两行中完成。

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

最佳答案

您需要将 HTTP 调用转换为您可以屈服的东西。目前写的很乱,所以是时候引入一些其他工具了——尤其是 promises。由于您使用的是 Koa,它在底层使用了一个名为 co 的库,因此 promises 可能是最简单的方法。我倾向于使用名为 Bluebird 的库来实现我的 promise ,还有其他选择。

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

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 对象中,您在外层的生成器运行器知道如何等待完成。

还有其他方法可以做到这一点,库(如共同请求)可以本地包装这些东西,但这是基本思想。

关于javascript - Node.js 生成器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32661097/

相关文章:

javascript - document.getElementById ("b1").checked 在 Mozilla 和 Chrome 中不起作用

javascript - 使用 Javascript 仅隐藏边框的一侧

node.js - 来自多个调用的流式 http 响应

node.js - 如何使用 NodeJS 向 mongodb 执行批量插入

python - 返回像 zip 这样的元组列表,使用推导式一次增量生成一个元组

javascript - 是否可以缓存整个网站,包括开始 html 页面和在没有互联网连接的情况下启动?

javascript - 根据另一个填充 1 个表单域

node.js - AWS AppSync : How to listen to change from DynamoDB (not by mutation)

python - Python 调试器会介入生成器吗?

python - 为什么 yield 可​​以指数化?