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中使用了它)。我遇到的问题是,即使服务器不可用,在错误事件之前也会调用end事件。因此,承诺不是用错误拒绝,而是用空数据解决了。我该如何解决这个问题?
答案 0 :(得分:1)
因此,根据http2/core.js
:
//创建后, Http2Session取得套接字的所有权。会议
//如果套接字尚未完全连接,则可能无法立即使用。
//在这种情况下,Http2Session将等待套接字连接。一次
// Http2Session准备就绪,它将发出自己的'connect'事件。
//
// Http2Session.goaway()方法将发送GOAWAY帧,发出信号
//到正在关闭的连接对等方。发送逃亡者
//框架没有其他作用。
//
//调用session.destroy()将立即删除Http2Session,
//使其不再可用。待处理的流和现有流将被销毁。
//绑定的套接字将被销毁。释放所有资源后,
//将发出'close'事件。请注意,待处理的流将
//使用特定的“ ERR_HTTP2_STREAM_CANCEL”错误进行销毁。现有开放
//流将使用传递给session.destroy()的相同错误销毁 //
// 如果使用错误调用destroy,则会发出“错误”事件
//紧接“关闭”事件。
//
//套接字和Http2Session生命周期是紧密绑定的。一旦一个
//销毁,另一个也应销毁。插座被破坏时
//发生错误,session.destroy()将被调用,并发生相同的错误。
//同样,如果在调用session.destroy()时出现错误,则会出现相同的错误
//将发送到套接字。
我认为这是预期的行为,首先是流closed
,然后发出error
。
根据上述文档,我添加了一个connect
事件以查看发生了什么。当服务器不可用时,它不会发出connect
事件,否则会发出。{p>
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
。
注意:这是我阅读源代码的意见,我不知道这是否正确。随时编辑答案并加以改善。