Node.js 发电机
Node.js Generators
我不确定如何构建 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() 函数 return 回调的最终字符串。
我是否也需要将回调设为生成器函数?我试过 var req = yield http.request(options, callback);
但由于那会停止请求,因此永远不会写入 POST 数据并且请求永远不会在以下两行中完成。
如果生成器不是解决此问题的正确方法,我还有哪些其他选择?
您需要将 HTTP 调用变成您可以屈服的东西。目前写的很乱,所以是时候引入一些其他工具了——尤其是 promises。由于您使用的是 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 对象中,您在外层的生成器运行器知道如何等待完成。
还有其他方法可以做到这一点,库(如共同请求)本地包装这些东西,但这是基本思想。
补充 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 标志时,Promise 已经内置到 Node v0.12.7 中,因此不需要额外的库
我不确定如何构建 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() 函数 return 回调的最终字符串。
我是否也需要将回调设为生成器函数?我试过 var req = yield http.request(options, callback);
但由于那会停止请求,因此永远不会写入 POST 数据并且请求永远不会在以下两行中完成。
如果生成器不是解决此问题的正确方法,我还有哪些其他选择?
您需要将 HTTP 调用变成您可以屈服的东西。目前写的很乱,所以是时候引入一些其他工具了——尤其是 promises。由于您使用的是 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 对象中,您在外层的生成器运行器知道如何等待完成。
还有其他方法可以做到这一点,库(如共同请求)本地包装这些东西,但这是基本思想。
补充 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 标志时,Promise 已经内置到 Node v0.12.7 中,因此不需要额外的库