0x8*_*890 4 javascript http node.js promise ecmascript-6
假设我有一个基本的HTTP服务器,用"foo"响应所有内容:
import http from 'http'
http.createServer((request, response) =>
Promise.resolve('foo\n').then(s => response.end(s))
).listen(8888)
Run Code Online (Sandbox Code Playgroud)
这有效,但当我将.then行更改为更短的版本时:
Promise.resolve('foo\n').then(response.end)
Run Code Online (Sandbox Code Playgroud)
它并没有结束回应.我必须遗漏一些非常愚蠢的东西但却想不到它是什么.
该end函数必须绑定到该response对象.你可以这样明确地做到这Function.prototype.bind一点
Promise.resolve('foo\n').then(response.end.bind(response))
Run Code Online (Sandbox Code Playgroud)
传递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();
Run Code Online (Sandbox Code Playgroud)
将打印thefourtheye.但是,如果我们做这样的事情
(function (func) {
func();
}(test.printName));
Run Code Online (Sandbox Code Playgroud)
它会打印出来undefined.因为test.printName实际上是函数对象,它不会有任何引用test.因此,当调用它时func(),this内部printName将引用全局对象,该对象不会name在其中定义属性.如果我们像这样绑定它
(function (func) {
func();
}(test.printName.bind(test)));
Run Code Online (Sandbox Code Playgroud)
test.printName.bind将返回一个新函数,它将实际调用test.printName上下文设置为test.这就是为什么它有效.