基本范围问题(JavaScript和节点)

嗨,我有一个非常简单的(我认为)问题,我似乎被困在。 我正在尝试创build下面的路线。

从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 }); 

移动res.json(req.body); 进入callback函数。

除了范围问题:它是asynchronous的,所以在你的代码中, 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); }); }); 

除了手头的问题之外,还有一个更为一般性的build议(或两三个)

什么可以帮助我这样的情况和“callback思考”是几乎从来没有使用内联callback函数:写代码只有一层深(当然模块模式加上一层),避免callback地狱! 命名所有callback,并将它们全部写在同一个(顶部)级别上。

 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时,你知道它是asynchronous的 – 在我自己的代码中添加一个清晰的注释(就像我上面所做的那样)。 所以我知道任何我写的asynchronous函数将无法访问任何asynchronous函数应该让我。 恕我直言,这样的评论是非常重要的 – 在Javascript中,没有办法知道callback函数是否是asynchronous的。 通常情况下,但是如果它是同步的,你期望不同步,你也可能会陷入困境! 所以我认为最好把它写成注释(在整个项目中总是使用完全相同的短string),这是一个forms化的代码注释。 顺便提一下,当你编写接受callback函数的函数的时候,要确保它们总是以同步或者asynchronous的方式调用,而不是两种方式(一些函数使用caching的值,并且能够立即返回结果,而不是启动asynchronousnetworking请求)。

基本上,书面结构并不反映这种风格的运行时情况 – 但是这是可以的,因为无论如何,运行时的情况是完全灵活的( 如果你想改变你使用的callback函数,或者增加另一个callback函数,你真的想要转换大量的代码行,而不是仅仅交换一个名字?更不用说提高可重用性了 )。 这是更容易阅读更长的callback式代码文件,然后几层深嵌套asynchronousfunction恕我直言。 尽可能避免function内部的function,除了模块模式。

命名函数对于debugging来说也更好,堆栈跟踪更容易阅读。

注意:我的示例代码留下了一个问题:如果这是在一个模块(或类)内,这些将是内部function,你可能需要确保正确的上下文/范围( this指向,如果你访问对象成员variables从这些函数内部)。 当这些函数在原型上时,它的工作原理是一样的。 所以这只是一个概念的例子,无视这个问题。

另一个注意事项:在调用callback函数时,在此样式variables中写入此前通过闭包(在本示例中为res内部函数可用的variables现在不得不作为函数参数使用。 这增加了一些复杂性 – 但另一方面迫使你在你自己的代码中创build干净的(er)API。 就我个人而言,我不喜欢过度依赖封闭来传递论据。 我太愚蠢了,我更喜欢有一个干净的接口定义,通过在其标题中使用一个函数使用的所有参数。 显然我并不孤单,这是function性编程最经常被吹捧的优点之一:)另外填充头是“干净”的参数也是在this对象属性。 我的小例子看起来有点“程序性”,但它只是用来说明一个问题。 当然,这属于模块化编程的更大范围。