为啥 HTTPs 节点库中的回调被调用两次?如何预防?
Posted
技术标签:
【中文标题】为啥 HTTPs 节点库中的回调被调用两次?如何预防?【英文标题】:Why is callback in HTTPs node library being called twice? How to prevent it?为什么 HTTPs 节点库中的回调被调用两次?如何预防? 【发布时间】:2019-11-28 20:27:23 【问题描述】:我有一个节点代码,它本质上是工作队列处理器。 我在大约 10 个进程的集群中运行它。
worker 处理的每个作业都使用下面粘贴的函数发出传出 HTTPs 请求:
注意 done();调用,它应该通知队列处理器作业处理已完成 - 成功或失败。 对于 https 请求,我使用包含“follow-redirects”模块的标准节点库。我遇到的问题是,每隔 X 分钟,我的一名工作人员就会崩溃,并显示以下错误消息。 据我了解,这意味着在“error_callback”中多次调用了“done()”。
如何防止这种行为? 在异常处理程序中嵌入 done() 调用会在这里工作吗?有没有更好的解决方案?
[2019-07-19 22:19:23] error: uncaughtException: the deferred callback has already been called
Error: the deferred callback has already been called
at callback (/root/node_modules/promise-callbacks/src/callbackBuilder.js:20:13)
at Object.error_callback (/root/lib/ways.js:115:9) (function from this file is attached below)
at RedirectableRequest.emit (events.js:189:13)
at ClientRequest.eventHandlers.(anonymous function) (/root/node_modules/follow-redirects/index.js:17:24)
at ClientRequest.emit (events.js:189:13)
at TLSSocket.socketErrorListener (_http_client.js:392:9)
at TLSSocket.emit (events.js:189:13)
at emitErrorNT (internal/streams/destroy.js:82:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:50:3)
at process._tickCallback (internal/process/next_tick.js:63:19)
done(null, host: this.host, code: statusCode); //notify queue processor of success with inclusion of results
done(e); //notify queue processor of failure with inclusion of error message
var http = require('follow-redirects').https;
exports.processLowLevel = function (url, index, done, SOCKET_TIMEOUT, HTTP_TIMEOUT, WRITE_RESULTS)
let url_parsed = require('url').parse(url);
let response_callback = function (resp)
console.log(`[$index] Response: $this.host - $resp.statusCode`);
done(null, host: this.host, code: resp.statusCode); //notify queue processor of success
return "";
;
let error_callback = function (e)
console.error(`[$index] Error callback: $this.host $e.message`);
e.host = this.host;
done(e); //notify queue processor of FAILURE
return "";
;
const options =
hostname: url_parsed.host,
path: url_parsed.path,
method: 'GET',
timeout: HTTP_TIMEOUT * 1000,
;
options.maxRedirects = 4;
let callback_data = 'host': url_parsed.host, 'index': index;
const req = http.request(options, response_callback.bind(callback_data));
req.on('error', error_callback.bind(callback_data));
req.end();
;
【问题讨论】:
【参考方案1】:不太确定这是否有帮助.. 但在 response_callback 而不是:
done(null, host: this.host, code: resp.statusCode); //notify queue processor of success
return "";
试试
return done(null, host: this.host, code: resp.statusCode);
和error_callback一样,试试:
return done(e);
【讨论】:
以上是关于为啥 HTTPs 节点库中的回调被调用两次?如何预防?的主要内容,如果未能解决你的问题,请参考以下文章
为啥即使回调参数与 XML 中的参数不匹配,GObject 方法仍会被调用?
为啥 UITableView 自定义单元格的第一个单元格总是在 Xcode 中的动作事件上被调用两次