嗨我有一个非常简单的(我认为)js问题,我似乎被困在了。 我正在尝试创建下面的路线。
从bEtsy函数中获取console.logged的是我希望在页面上显示的内容。但是“身体”在该范围之外是不可用的。
app.get('/api/etsy/getListings',function(req, res){
bEtsy.getAllListings(req, res, function(err, body) {
// console.log(body);
});
res.json(req.body); // both this and res.json(body) does not work
});
答案 0 :(得分:1)
将res.json(req.body);
移至回调函数中。
除了范围界定问题:它是异步的,所以在你的代码中,它会在res.json(req.body)
运行后很长时间被调用。
app.get('/api/etsy/getListings', function(req, res) {
bEtsy.getAllListings(req, res, function(err, body) {
res.json(body);
//console.log(body);
});
});
除了手头的问题之外,还有更一般的建议(或两三件):
有什么帮助我解决这种情况和“回调思维”几乎从不使用内联回调函数:编写代码只有一层深(当然还有一层模块模式),避免回调地狱!命名所有回调并将它们全部写在同一(顶层)。
function allListingsReceived(err, body, res) {
res.json(body);
//console.log(body);
}
function getListings(req, res) {
// ASYNC
bEtsy.getAllListings(req, res, allListingsReceived);
}
//ASYNC
app.get('/api/etsy/getListings', getListings);
这使我能够更好地了解实际的呼叫顺序。在这种情况下,当调用getAllListings
时,您知道它是异步的 - 在我自己的代码中,我添加了一个明确的注释(就像我上面所做的那样)。所以我知道我要编写的任何东西后异步函数将无法访问异步函数应该得到的任何东西。恕我直言这样的评论重要 - 在Javascript中无法知道回调函数是否是异步的。通常它是,但如果它是同步的,你期望异步,你也可能遇到麻烦!所以我认为最好把它写成注释(在整个项目中总是完全相同的短字符串),一个形式化的代码注释。顺便提一下导致另一个问题:当你编写接受回调函数的函数时,确保它们总是同步或异步地调用它,从不两种方式(某些函数使用缓存值并且能够立即返回结果而不是启动异步。网络请求。)
基本上,写入的结构并不反映这种风格的运行时情况 - 但这没关系,因为运行时情况无论如何都是完全灵活的(如果你想改变你使用的回调函数,或者添加另一个在这两者之间,您是否真的希望转换大量的代码而不仅仅是交换名称?更不用说提高可重用性的容易程度了。这在更长的回调式代码文件中更容易阅读,然后几层深嵌套异步函数恕我直言。除了模块模式之外,尽可能避免在函数内部使用函数。
命名函数也可以更好地进行调试,堆栈跟踪更容易阅读。
注意:我的示例代码会打开一个问题:如果这是一个模块(或类),那么这些将是内部函数,您可能必须确保正确的上下文/范围(其中{{1}如果从这些函数内部以这种方式访问对象成员变量,则指向。当这些功能在原型上时,它的工作方式相同。所以这只是一个忽略这个问题的一般概念例子。
另一个注意事项:当在这个样式变量中写入以前通过闭包可用于内部函数时 - 在本例中为this
- 现在必须在调用回调函数时作为函数参数使用。这增加了一些复杂性 - 但另一方面迫使您在自己的代码中创建干净的(呃)API。就个人而言,我不喜欢过度依赖闭包传递参数。我太傻了,我更喜欢通过让函数在其标题中使用所有参数来获得干净的接口定义。显然我并不孤单,这是函数式编程最常被吹捧的优点之一:)用res
下的对象属性填充带有“干净”参数的标题的替代方法。我的小例子看起来有点“程序性”,但它只能说明一个单点。当然,这属于模块化编程的更大背景。