2011-09-01 87 views
1

我在使用Node.js应用程序进行变量作用域时遇到问题,我通常理解变量作用域在/围绕某个函数的工作方式(在这种情况下,匿名回调函数)。在Javascript中通过变量作用域维护变量

我正在与之争斗的是什么是通过匿名回调链/洞维持可变物的最佳方式。在通常情况下,我可以将变量传递给函数,但是因为我使用猫鼬(mongodb ORM),所以我不能将自己的变量传入。因此,不得不求助于每次更深入地定义变量回电话。

这样做的最好方法是什么?

下面是我的代码,我结束了在不确定的时间越来越变量我想用他们的tweeting:

var userBid = tag.user; 

User.find({id: userAid}, function(err, userA){ 

    if (err) {console.log("Error getting user A for tweeting ", err)} 
    else { 
    var userAName = userA.twitter.screenName; 
    var userBid2 = userBid; 
    User.find({id: userBid2}, function(err, userB){ 

     if (err) {console.log("Error getting user B for tweeting ", err)} 
     else { 

     var action = "@"+ userAName + " just claimed some of @" + userB.twitter.screenName + " 's turf as their own."; 

     twitterClient.updateStatus(action, function(err, resp){ 
      if (!err) { 
      console.log("Tweeted: ", action); 
      } else { 
      console.log("TwitBot error:", err); 
      } 
     }); 
     } 
    }); 
    } 
}); 

肯定有处理这更好的办法... 任何帮助是多少赞赏。

+1

这不是PHP/C/Java的令行禁止的userAName变量到匿名函数!你不必传递你的变量。它们将始终通过范围查找链可用......只需在范围的顶层声明它们(就像现在一样),然后就可以从这些函数内部访问它们。 **不需要将它们传递给兔子洞!! ** –

+0

嗯......如果是这样的话,为什么我的变量没有定义?绑定/ currying的原因是什么,请参阅@Raynos的回答低于 – Christopher

+0

迟到比永远更好:您的userBid已被正确定义,并且应该可以在您的查询中访问。它是在你的函数之外定义的,因此可以在你的函数内部看到。只要确保该变量实际上已正确定义,并且该tag.user不是未定义的。一个简单的console.log(userBid)应该解决这个问题。 – Jorre

回答

2
User.find({ 
    id: userAid 
}, function(err, userA) { 
    if (err) throw err; 
    else { 
     User.find({ 
      id: tag.user 
     }, (function(userAName, err, userB) { 
      if (err) throw err; 
      else { 
       var action = "@" + userAName + " just claimed some of @" + userB.twitter.screenName + " 's turf as their own."; 
       twitterClient.updateStatus(action, function(err, resp) { 
        if (!err) { 
         console.log("Tweeted: ", action); 
        } else { 
         console.log("TwitBot error:", err); 
        } 
       }); 
      } 
     }).bind(null, userA.twitter.screenName)); 
    } 
}); 

要么使用闭合范围(tag.user可通过封闭件),或使用.bind变量绑定到一个函数。

例如,我们已经做

(function(userAName, normal, arguments, here) { 

}).bind(null, userAName)); 
+0

感谢您的回答,我对这部分感到困惑:'(function(userAName,err,userB){'我担心看到这个回调被第三方(猫鼬)触发时, 'userAName'中,我的印象是第一个参数是'err' ...或者是否可以安全地按照你的建议去做? – Christopher

+0

@Christopher就是'.bind'的工作方式,它返回一个新的函数第一个参数锁定并在第一个参数后插入其余参数 – Raynos

+0

太棒了!谢谢! – Christopher