Using Node `response.end` method with a 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 line .then

to a shorter version:

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

      

This does not complete the answer. I must be missing something very dumb, but I can't think of what it is.

+3


source to share


1 answer


The function end

must be bound to an object response

. You can explicitly do it Function.prototype.bind

like this

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

      


When you pass a function response.end

in then

, you are actually passing a function object to a function then

. The actual binding between function and object is response

broken. For example, inside a function end

, if they refer to an object response

on this

, it won't be there since we broke it. This is why we have to explicitly bind the function object to 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 it test.printName

is actually a function object and it will not refer to test

. So when it is called with func()

, this

internally it printName

will refer to a global object that will not have a property name

defined in it. If we link it like this:

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

      

test.printName.bind

will return a new function that will actually call test.printName

with the context set as test

. This is why it works.

+6


source







All Articles