Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Node.js is giving different HTTP responses with different timeouts

I’m using Node.js for backend (I’m just testing it with localhost), and I noticed that with this code…

response.writeHead(200, { 'Content-Type': 'text/html' });
fs.readFile('index.html', (_err, data) => {
    response.end(data);
});


response.writeHead(200, {'Content-Type': 'application/json'})
const responseBody = { headers, method, url, body };
response.write(JSON.stringify(responseBody));
response.end();

…the second response.end() call was "overwriting" the first one (the html page was never shown).


So I decided to use setTimeout to see if I could make appear the content of index.html first, and then after a few seconds the application/json response…

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

setTimeout(() => {
    response.writeHead(200, {'Content-Type': 'application/json'})
    const responseBody = { headers, method, url, body };
    response.write(JSON.stringify(responseBody));
    response.end();
}, 1000);

…but after the first response.end() call I could never see the json appear.


Then I had a strange idea, I decided to change the timeout from 1000ms to 1ms, and the html content was never shown, I immediately (or maybe after 1ms, which is such a small amount of time) saw the json content.

I tried with 10ms but it worked as with 1000ms, then I tried with 2ms, and refreshing the page it sometimes showed json and sometimes html.


How is this possible? The response.end() function doesn’t wait until the response has ended? Is it caused by something else? Thank you in advance.

>Solution :

I think you’re correct in saying that response.end() does not wait until file transfer is actually ended.

I actually learned that while using express:
If you do response.sendFile(...) followed by response.end() in the same function, then no actual file is sent (the response is ‘closed’ before the file can actually be sent), it just gives an empty response.


Edit:

In your first code, the JSON writing is always executed earlier than the readFile callback. (The readFile callback is having an asynchronous behavior.)


But once you have the timeout, there is a race between the "timeout callback" and "readFile callback".

Since file loading times can vary, it may be sometimes faster than the timeout and sometimes slower. But whichever callback ‘wins the race’, it will call the response.end(), preventing the other one from sending anything.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading