使用 Node 的 `response.end` 方法和 promise
Using Node's `response.end` method with promise
假设我有一个基本的 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)
它不会结束响应。我一定是遗漏了一些非常愚蠢的东西,但想不出它是什么。
end
函数必须绑定到 response
对象。你可以明确地这样做, Function.prototype.bind
这样
Promise.resolve('foo\n').then(response.end.bind(response))
当你将response.end
传递给then
函数时,实际上是将函数对象传递给then
函数。函数和 response
对象之间的实际绑定被破坏了。例如,在 end
函数中,如果他们用 this
引用 response
对象,它就不会存在,因为我们已经破坏了它。这就是为什么我们必须显式地将函数对象与实际对象绑定。
例如,
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()
调用时,printName
中的 this
将引用全局对象,其中不会定义 name
属性。如果我们这样绑定它
(function (func) {
func();
}(test.printName.bind(test)));
test.printName.bind
将 return 一个新函数,该函数将实际调用 test.printName
,上下文设置为 test
。这就是它起作用的原因。
假设我有一个基本的 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)
它不会结束响应。我一定是遗漏了一些非常愚蠢的东西,但想不出它是什么。
end
函数必须绑定到 response
对象。你可以明确地这样做, Function.prototype.bind
这样
Promise.resolve('foo\n').then(response.end.bind(response))
当你将response.end
传递给then
函数时,实际上是将函数对象传递给then
函数。函数和 response
对象之间的实际绑定被破坏了。例如,在 end
函数中,如果他们用 this
引用 response
对象,它就不会存在,因为我们已经破坏了它。这就是为什么我们必须显式地将函数对象与实际对象绑定。
例如,
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()
调用时,printName
中的 this
将引用全局对象,其中不会定义 name
属性。如果我们这样绑定它
(function (func) {
func();
}(test.printName.bind(test)));
test.printName.bind
将 return 一个新函数,该函数将实际调用 test.printName
,上下文设置为 test
。这就是它起作用的原因。