node.js - 在“结束”事件之后调用“错误”事件?
问题描述
const http2 = require('http2');
const fs = require('fs');
function APICall(){
return new Promise(function(resolve,reject){
const client = http2.connect('https://localhost:8443', {
ca: fs.readFileSync('localhost-cert.pem')
});
client.on('error', (err) => console.error(err));
const req = client.request({ ':path': '/' });
req.on('error', (error) => {
console.log("error",error)
reject("Could not connect with server");
});
req.setEncoding('utf8');
let data = '';
req.on('data', (chunk) => { data += chunk; });
req.on('end', () => {
console.log(`\n${data}`);
resolve(data);
});
});
}
我创建了一个 http2 客户端(使用官方网站中提供的示例,除了我在 Promise 中使用它)。我遇到的问题是,即使我的服务器不可用,也会在错误事件之前调用结束事件。因此,promise 不是用错误拒绝,而是用空数据来解决。我该如何解决这个问题?
解决方案
所以根据http2/core.js
:
// 创建后,Http2Session 获得套接字的所有权。如果套接字尚未完全连接,会话
// 可能无法立即使用。
// 在这种情况下,Http2Session 将等待套接字连接。一旦
// Http2Session 准备就绪,它将发出自己的“连接”事件。
//
// Http2Session.goaway() 方法将发送一个 GOAWAY 帧,
向连接的对等方发出信号 // 正在关闭。然而,发送一个 goaway
// 帧没有其他效果。
//
// 调用 session.destroy() 将立即拆除 Http2Session,
// 使其不再可用。待处理的和现有的流将被销毁。
// 绑定的套接字将被销毁。一旦所有资源都被释放,
// 'close' 事件将被触发。请注意,待处理的流将被
销毁 // 使用特定的“ERR_HTTP2_STREAM_CANCEL”错误。现有的打开
// 流将使用传递给 session.destroy() 的相同错误被销毁
//
//如果调用destroy时出现错误,则将在“关闭”事件之后立即发出“错误”
事件。
//
// 套接字和 Http2Session 生命周期是紧密绑定的。一旦一个被
// 销毁,另一个也应该被销毁。当套接字被销毁时
// 出现错误, session.destroy() 将被调用并出现同样的错误。
// 同样,当 session.destroy() 调用出错时,同样的错误
// 将被发送到套接字。
我认为这是首先出现流closed
然后error
发出的预期行为。
根据上面的文档,我添加了一个connect
事件来查看发生了什么。当服务器不可用时,它不会发出connect
事件,否则它会发出。
const http2 = require('http2');
const fs = require('fs');
function APICall(){
return new Promise(function(resolve,reject){
const client = http2.connect('http://localhost:8443', {
// ca: fs.readFileSync('localhost-cert.pem')
});
client.on('error', (err) => console.error('client error'));
const req = client.request({ ':path': '/' });
client.on('connect', ()=>console.log('connect'))
req.on('error', (error) => {
reject("Could not connect with server");
});
req.setEncoding('utf8');
let data = '';
req.on('data', (chunk) => { data += chunk; });
req.on('end', () => {
console.log('ended');
console.log(`\n${data}`);
resolve(data);
});
});
}
connect
ended
ended
client error
因此,您可以检查是否使用该connect
事件data
。
注意:这是我阅读源代码的看法,我不知道这是否正确。随意编辑答案并改进它。