我正在一个项目中工作,该项目将Node.js用于原坂 (一个smtp服务器)插件。
这是Node.JS,我在回调时遇到了一点小问题。我无法将这个特定的代码转换为使用回调。
所以,这就是我的代码:
exports.hook_data = function (next, connection) {
connection.transaction.add_body_filter('', function (content_type, encoding, body_buffer) {
var header = connection.transaction.header.get("header");
if (header == null || header == undefined || header == '') return body_buffer;
var url = 'https://server.com/api?header=' + header ;
var request = require('request');
request.get({ uri: url },
function (err, resp, body) {
var resultFromServer = JSON.parse(body);
return ChangeBuffer(content_type, encoding, body_buffer, resultFromServer);
}
);
});
return next();
}此代码不能工作,因为它不会等待请求的回调才能继续。我需要在next()之前完成请求;
这些都是要求:
exports.hook_data的末尾,必须返回next()。但它只需要在请求之后才能返回。Buffer中返回一个add_body_filter,但我需要使用从服务器获取的信息创建缓冲区。header),该参数仅包含在add_body_filter中。因此,问题是我无法在add_body_filter之前发出请求并将结果放入回调中,因为我需要的请求参数仅在add_body_filter中。
有什么建议吗?
发布于 2015-12-15 20:31:30
除非您愿意使用同步、阻塞函数,否则不可能满足已编号的需求。
我会检查每个需求背后的原因,看看你是否以不同的方式完成了你的目标。
从表面上看,只要看一下代码,我就会寻找一种方法来更改exports.hook_data的契约,以便您能够从request.get回调内部调用request.get。
发布于 2015-12-20 03:43:48
使用Async.js或承诺。
异步实现:
exports.hook_data = function (next, connection) {
async.waterfall([
function( done ) {
connection.transaction.add_body_filter('', function( content_type, encoding, body_buffer ) {
var header = connection.transaction.header.get("header");
if ( header == null || header == undefined || header == '' ) {
done(null, body_buffer);
}
done(null, header);
});
},
function( header, done ) {
var url = 'https://server.com/api?header=' + header;
var request = require('request');
request.get({ uri: url },
function( err, resp, body ) {
// do something if there's an error
var resultFromServer = JSON.parse(body);
done(null, ChangeBuffer(content_type, encoding, body_buffer, resultFromServer));
}
);
}
], function( error, buffer ) {
// do something if there's error
next(buffer);
});
}这里有很多东西,我建议您阅读async.js#waterfall上的文档。本质上,它将每个异步调用分解为on函数块,并等待它返回,然后再继续到下一个块。
同样,由于这些都是异步的,节点将这些任务提交给IO事件循环,并在那里处理(非阻塞)。当这个线程等待时,它可能会继续到下一个请求,而这个请求正在等待。
发布于 2015-12-23 13:03:05
查看事务对象 & 标头对象的Haraka手册,我发现add_body_filter上没有任何头的依赖关系。而且,您的代码不显示对add_body_filter的任何依赖。所以你的第三个要求看起来是无效的。
考虑到这一点,我认为遵循伪代码(因为我无法测试)应该对您有用。
exports.hook_data = function (next, connection) {
var header = connection.transaction.header.get("header");
if (header == null || header == undefined || header == '') {
return next();
var url = 'https://server.com/api?header=' + header ;
var request = require('request');
request.get({ uri: url },
function (err, resp, body) {
var resultFromServer = JSON.parse(body);
connection.transaction.add_body_filter('', function (content_type, encoding, body_buffer) {
return ChangeBuffer(content_type, encoding, body_buffer, resultFromServer);
});
next();
}
);
}如果Haraka手册没有强调Header对add_body_filter的依赖性,或者您根据实际经验发现了它,那么Quy的方法似乎是可行的。
如果你想知道何时使用next() v/s返回next()
https://stackoverflow.com/questions/34298589
复制相似问题