以无积分方式表达和调用 response.json 在 Promise.then 中不起作用
Express and calling response.json in a point free fashion doesn't work in Promise.then
今天有件事让我很吃惊。我遇到了一堆快速路由处理程序,基本上看起来像这样(还有更多真实的函数调用,但为了易读性:
app.get('/api/foo', (req, resp) => {
Promise.resolve({one: 1})
.then(data=>resp.json(data))
})
所以我,作为聪明的 javascript 程序员,认为我可以摆脱匿名函数,让 then 函数直接调用 resp.json:
app.get('/api/foo', (req, resp) => {
Promise.resolve({one: 1})
.then(resp.json)
})
但是当我尝试这样做时,我从未得到响应并在节点控制台中看到:
Unhandled promise rejection (rejection id: 1): TypeError: Cannot read
property 'app' of undefined
在我看来.then(resp.json) and .then (data=>resp.json(data)) 应该是等价的。可以肯定的是,这是一个范围的事情,但我喜欢一个解释,也许还有一个解决方法。
这是因为 resp
是一个具有自身属性的对象,因此 json
函数使用的数据很可能包含在 resp
对象中。
当您将函数 resp.json
本身传递给 then
时,您并没有将 resp
对象或其任何信息与其一起传递。 本质上,then
调用只是 "borrowing" 来自 resp
对象 的函数 json
。不过只是函数体本身,没有作用域或隐式值。
更有可能的是,json
的函数体在某处使用了 this
,此时您将得到一个无效的(可能是全局的)对象,而不是 resp
。
要补救,你可以
Promise.resolve({one: 1})
.then(resp.json.bind(resp))
它们不一样,因为 the this
operator works in javascript。
基本上,resp.json(data)
用this===resp
调用函数,而resp.json
用this===global
调用函数。
要修复它,请传递带有绑定参数的函数 .then(resp.json.bind(resp))
(或使用箭头函数)。
今天有件事让我很吃惊。我遇到了一堆快速路由处理程序,基本上看起来像这样(还有更多真实的函数调用,但为了易读性:
app.get('/api/foo', (req, resp) => {
Promise.resolve({one: 1})
.then(data=>resp.json(data))
})
所以我,作为聪明的 javascript 程序员,认为我可以摆脱匿名函数,让 then 函数直接调用 resp.json:
app.get('/api/foo', (req, resp) => {
Promise.resolve({one: 1})
.then(resp.json)
})
但是当我尝试这样做时,我从未得到响应并在节点控制台中看到:
Unhandled promise rejection (rejection id: 1): TypeError: Cannot read property 'app' of undefined
在我看来.then(resp.json) and .then (data=>resp.json(data)) 应该是等价的。可以肯定的是,这是一个范围的事情,但我喜欢一个解释,也许还有一个解决方法。
这是因为 resp
是一个具有自身属性的对象,因此 json
函数使用的数据很可能包含在 resp
对象中。
当您将函数 resp.json
本身传递给 then
时,您并没有将 resp
对象或其任何信息与其一起传递。 本质上,then
调用只是 "borrowing" 来自 resp
对象 的函数 json
。不过只是函数体本身,没有作用域或隐式值。
更有可能的是,json
的函数体在某处使用了 this
,此时您将得到一个无效的(可能是全局的)对象,而不是 resp
。
要补救,你可以
Promise.resolve({one: 1})
.then(resp.json.bind(resp))
它们不一样,因为 the this
operator works in javascript。
基本上,resp.json(data)
用this===resp
调用函数,而resp.json
用this===global
调用函数。
要修复它,请传递带有绑定参数的函数 .then(resp.json.bind(resp))
(或使用箭头函数)。