Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Node's `response.end` method with promise

Suppose I have a basic HTTP server that responds to everything with "foo":

import http from 'http'

http.createServer((request, response) =>
  Promise.resolve('foo\n').then(s => response.end(s))
).listen(8888)

This works, but when I change the .then line to a shorter version:

Promise.resolve('foo\n').then(response.end)

It doesn't end the response. I must be missing something very dumb but can't think of what it is.

like image 452
0x8890 Avatar asked Mar 17 '23 02:03

0x8890


1 Answers

The end function has to be bound to the response object. You can explicitly do that, with Function.prototype.bind like this

Promise.resolve('foo\n').then(response.end.bind(response))

When you pass response.end to then function, you are actually passing the function object to the then function. The actual binding between the function and the response object is broken. For example, inside the end function, if they refer the response object with this, it will not be there as we have broken it. That is why we have to explicitly bind the function object with the actual object.

For example,

function Test(name) {
    this.name = name;
}

Test.prototype.printName = function () {
    console.log(this.name);
}

var test = new Test("thefourtheye");
test.printName();

will print thefourtheye. But if we do something like this

(function (func) {
    func();
}(test.printName));

it will print undefined. Because test.printName is actually the function object and it will not have any reference to test. So when it is invoked with func(), the this inside printName will refer the global object, which will not have name property defined in it. If we bind it like this

(function (func) {
    func();
}(test.printName.bind(test)));

test.printName.bind will return a new function which will actually invoke test.printName with the context set as test. That is why it works.

like image 171
thefourtheye Avatar answered Mar 31 '23 05:03

thefourtheye