将函数的执行同步为 node.js 中的回调参数
Synchronising the execution of a function as callback parameter in node.js
我正在学习js(特别是node&express(,目前正在努力理解什么是同步,什么不是。
目前,我有需要向 B 型服务发送请求的 A 型服务。我想将这些请求聚合到一个通用函数中,以便所有 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 类型服务的执行在到达回调函数代码之前已经完成.我认为回调是堆叠的,执行将经过整个堆栈,所以我很难说出这个链中到底什么是异步的。
有人可以对此事有所了解吗?如何同步此链?这里有一些最佳实践?
您现在看到的核心问题是'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
返回一个事件发射器对象,但是我也建议将你的回调重新设计为基于事件的,这样你就不会混合范式。
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();
}
相关文章:
- 要求未定义JS回调参数
- 从新的WordPress媒体上传程序获取JS回调
- 重构DRY代码的Node.JS回调
- Material Design Lite所有元素加载JS回调
- js回调到基于生成器的代码
- Flux+React.js-回调操作是好是坏
- 节点.js回调函数不返回值
- 理解node.js回调
- node.js回调函数generanddb
- JSON和JS回调函数
- 从嵌套在函数中的Node.js回调返回对象
- 循环中的Node.js回调具有错误的迭代器值
- 将变量传递给 Node.JS 回调函数
- 防止动画多次运行 - js 回调
- 引导框.js回调不起作用
- 使用 map() 和一个具有一个附加参数的函数的 JS 回调
- 异步等待.js回调中的多个参数
- 定义节点.js回调的超时
- 节点.js回调如何异步
- 节点.js回调工作不正常