Node.js:http完成事件,响应关闭事件和响应结束事件之间的区别

时间:2019-02-05 00:15:13

标签: javascript node.js http events

我是Node.js的新手,在查阅了文档并尝试了http.on('finish'),res.on('close')和res.on('end')之后,我不明白它们之间有什么不同。

http.get(url, res => {

        res.setEncoding('utf8'); // returns string object to data event
        res.on('data', string => {
            const responseObj = responseDataList.find(responseObj => {
                return responseObj.url === url;
            });
            responseObj.data += string;
        });
        res.on('close', () => {
            console.log('[Interruption] connection closed before response was ended.');  // Never fires
        })

        res.on('error', console.error);

        // TODO: find out difference between response.end and response.close and http.finish events
        res.on('end', (data, encoding) => {
            // Seems to fire at the same time that http.on('finish') fires
            current++;
    
            if (counter === current) {
                responseDataList.forEach(responseObj => {
                    console.log(responseObj.data);
                })
            }
        });
    })
    .on('error', console.error)
    .on('finish', () => {
        // Seems to fire at the same time that res.on('end') fires
        console.log('response sent')
    }); // emitted when the response is sent to the OS (not when it is received by the client)

http.on('finish'),res.on('end'),res.on('close')何时触发,它们有何不同?

1 个答案:

答案 0 :(得分:2)

http.get使用res对象调用回调时,它会返回http.ClientRequesthttp.ClientRequest继承自Stream

因此,根据docs

  

调用finish方法之后,将发出stream.end()事件,并且所有数据都已刷新到基础系统。

http.get的情况下,发出请求后立即调用stream.end()(请参见here)。 N.B.呼叫stream.end()不同于监听res.on('end')事件。

因此,对于http.getfinish事件将在发出请求后立即触发,然后res对象事件将开始触发。

您的res对象是一个HTTP.IncomingMessage,它实现了Readable Stream接口

根据Readable Stream文档:

  

当没有更多数据要从流中使用时,将发出“结束”事件。

因此end首先触发,然后close

Readable Streams

  

当流及其任何基础资源(例如文件描述符)已关闭时,将发出'close'事件。该事件表示将不再发出事件,也不会进行进一步的计算。

因此事件按以下顺序触发:finishendclose