假设我有一个基本的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)
它并没有结束回应。我必须遗漏一些非常愚蠢但却无法想象的东西。
答案 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
。这就是它运作的原因。