Undocumented response.finished in node.js

2019-09-09 17:12发布

问题:

Just starting off with node.js and following Node Cookbook but I am stuck on URL routing part.

here is the code from the book itself:

var http = require('http');
var path = require('path');

var pages = [
    {route: '', output: 'Woohoo!'},
    {route: 'about', output: 'A simple routing with Node example'},
    {route: 'another page', output: function() {return 'Here\'s '+this.route;}},
    ];

http.createServer(function (request, response) {

   var lookup = path.basename(decodeURI(request.url));

    pages.forEach(function(page) {

        if (page.route === lookup) {
            response.writeHead(200, {'Content-Type': 'text/html'});
            response.end(typeof page.output === 'function'? page.output() : page.output);
        }
    });
    if (!response.finished) {  // couldn't find any documentation for response.finished

        response.writeHead(404);
        response.end('Page Not Found!');
    }
}).listen(8080);

console.log('Server started');

Though code runs without any errors and seems it does what they meant but looking to the node.js documetation and searching on Google for response.finished doesn't yields any result.

and here is the quote from the book in context of explaining response.finished

Could you please explain what the actually meant by that quotation or any citation for response.finished.

回答1:

It's declared here and set here. TL;DR: when response.end() is (almost) done, the finished property is set to true (response is an instance of http.OutgoingMessage or a subclass).

I actually have to disagree with the comment about it not being a race condition, because I think it is. Even though forEach isn't asynchronous itself, in this case it calls asynchronous functions (writeHead() and end()). If those functions take a bit of time, the check for response.finished might be called too soon and you'll end up with an error.

Also, I wonder if finished should be used at all. It's not documented and not exposed to the outside world through a method. In other words, it might work now but there's no guarantee it will keep working in the future.



回答2:

As of this date, response.finish is documented (actually per the doc it was introduced in v0.0.2)

From the Node API Official Documentation,

response.finished

Added in: v0.0.2

Boolean value that indicates whether the response has completed. Starts as false. After response.end() executes, the value will be true.