首页 > 解决方案 > 在“结束”事件之后调用“错误”事件?

问题描述

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 不是用错误拒绝,而是用空数据来解决。我该如何解决这个问题?

标签: node.jshttp2

解决方案


所以根据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);
        });
    });
}

http://localhost:8443启动时:

connect
ended

http://localhost:8443关闭时:

ended
client error

因此,您可以检查是否使用该connect事件data

注意:这是我阅读源代码的看法,我不知道这是否正确。随意编辑答案并改进它。


推荐阅读