[英]Synchronising the execution of a function as callback parameter in node.js
我正在学习js(特别是node&express),目前正努力理解什么是同步,什么不是同步。
目前,我可以说A型服务需要将请求发送到B型服务。 我想将这些请求聚合到一个通用函数中,以便所有A型服务都可以使用它。
A型服务代码(直接在router.post中)
var post_data = <some data>
sendBServicePost(post_data,function (out_data) {
var resp_data = JSON.parse(out_data);
if (resp_data.status == "OK") {
var msg = 'Request OK : '+out_data;
console.log(msg);
res.json({ status:"OK", message:msg});
}
else
{
var msg = 'Login KO: '+out_data;
console.log(msg);
res.json({ status:"KO_FUNC", message:msg});
}
}).on('error',function (e) {
var msg = 'Error with call: ' + e.message;
console.log(msg);
res.json({ status:"KO_TECH", message:msg});
});
这是罪魁祸首函数的代码:
function sendBServicePost(post_data,callback) {
var post_options = {
// Some options
};
// Sending request
var post_req = http.request(post_options, function(post_res) {
post_res.on('data', function(out_data) {
callback(out_data);
});
});
post_req.write(post_data);
post_req.end();
}
因此,发生的事情是我收到一条错误消息,说我在尝试发送响应时正在尝试添加响应头,这是我想发生的,因为在到达回调函数代码之前A型服务的执行已经完成。 我以为回调是堆叠的,执行将遍历整个堆栈,因此,我很难说清此链中到底是什么异步。
有人可以阐明这件事吗? 如何同步此链? 这里有一些最佳做法?
function sendBServicePost(post_data,callback) {
var post_options = {
// Some options
};
// << While this part is executing >>
var post_req = http.request(post_options, function(post_res) {
post_res.on('data', function(out_data) {
// Anything you want to execute synchronously you can write here, before or after callback.
callback(out_data);
});
});
// << This part is also executing >>
post_req.write(post_data);
post_req.end();
}
您现在看到的核心问题是'data'
事件可能会对部分数据触发多次,因此您将多次调用callback
,因此将多次调用res.json
,这将触发您的错误。
另外, node
通常对传递回调以将第一个参数用作错误的代码进行标准化,因此我建议以下内容:
function sendBServicePost(post_data, callback) {
var post_options = {
// Some options
};
// Sending request
var post_req = http.request(post_options, function(post_res) {
var pieces = [];
post_res.on('data', function(out_data) {
pieces.push(out_data);
});
post_res.on('end' function(){
callback(null, Buffer.concat(pieces));
});
post_res.on('error', function(err){
callback(err, null);
});
});
post_req.on('error', function(err){
callback(err, null);
});
post_req.write(post_data);
post_req.end();
}
像这样称呼:
var post_data = <some data>
sendBServicePost(post_data, function (err, out_data) {
if (err){
var msg = 'Error with call: ' + e.message;
res.json({ status: "KO_TECH", message: msg});
return;
}
var resp_data = JSON.parse(out_data);
if (resp_data.status == "OK") {
var msg = 'Request OK : ' + out_data;
res.json({status: "OK", message: msg});
} else {
var msg = 'Login KO: ' + out_data;
res.json({status: "KO_FUNC", message: msg});
}
});
如果您确实希望代码更像.on('error',
那么您总是可以从sendBServicePost
返回一个事件发射器对象,但是我还建议您将回调修改为基于事件的,这样您就不会混淆范式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.