使用Node的`response.end`方法和promise

时间:2015-05-11 15:41:30

标签: javascript node.js http promise ecmascript-6

假设我有一个基本的HTTP服务器,用“foo”响应所有内容:

import http from 'http'

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

这可行,但当我将.then行更改为较短版本时:

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

它并没有结束回应。我必须遗漏一些非常愚蠢但却无法想象的东西。

1 个答案:

答案 0 :(得分:7)

end函数必须绑定到response对象。您可以使用Function.prototype.bind这样明确地执行此操作

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

当您将response.end传递给then函数时,实际上是将函数对象传递给then函数。函数与response对象之间的实际绑定被破坏。例如,在end函数内部,如果他们使用response引用this对象,那么它就不会存在,因为我们已经破坏了它。这就是我们必须将函数对象与实际对象显式绑定的原因。

例如,

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

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

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

将打印thefourtheye。但是,如果我们做这样的事情

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

它会打印undefined。因为test.printName实际上是函数对象,所以它不会引用test。因此,当使用func()调用它时,this内的printName将引用全局对象,该对象不会在其中定义name属性。如果我们像这样绑定它

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

test.printName.bind将返回一个新函数,该函数将实际调用test.printName并将上下文设置为test。这就是它运作的原因。