Javascript Node.js生成器
我不确定如何构造Javascript生成器代码,使其能够正确执行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() {
...
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库,还有其他选择吗?我试图遵循代码,但无法使与代码的关联正确地工作,就像一个符咒——感谢您澄清了我的承诺与生成器混淆