javascriptnode.jshttpevents

Node.js: Difference between http finish event, response close event, and response end event


I'm new to NodeJS and after looking in the documentation and experimenting with the http.on('finish'), res.on('close'), and res.on('end'), I do not understand how each are different.

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)

When do each one fire and how are they different?


Solution

  • As soon as http.get calls your callback with the res object it returns an http.ClientRequest. The http.ClientRequest inherits from Stream.

    So, according to the docs:

    The finish event is emitted after the stream.end() method has been called, and all data has been flushed to the underlying system.

    In the case of http.get, stream.end() is called immediately after making the request (See here). N.B. calling stream.end() is different from listening to the res.on('end') event.

    So for http.get, the finish event will fire immediately after making the request and then the res object events will start firing.

    Your res object is an HTTP.IncomingMessage which implements the Readable Stream interface

    According the the Readable Stream docs:

    The 'end' event is emitted when there is no more data to be consumed from the stream.

    So end fires first then close

    Also for Readable Streams

    The 'close' event is emitted when the stream and any of its underlying resources (a file descriptor, for example) have been closed. The event indicates that no more events will be emitted, and no further computation will occur.

    So the events fire in this order: finish, end, close