【问题标题】:Maintaining variables through variable scope in Javascript通过 Javascript 中的变量范围维护变量
【发布时间】:2011-11-08 15:27:31
【问题描述】:

我在使用我正在制作的 Node.js 应用程序中处理变量范围时遇到了麻烦,通常我了解变量范围在函数中/周围的工作原理(在本例中为匿名回调函数)。

我正在与之斗争的是通过匿名回调链/漏洞维护变量的最佳方法是什么。通常我可以将变量传递给函数,但是因为我使用的是猫鼬(mongodb ORM),所以我不能传递我自己的变量。因此不得不在每一步中一遍又一遍地定义变量回调。

最好的方法是什么?

下面是我的代码,当我想将它们用于推文时,我最终会得到未定义的变量:

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

当然有更好的方法来处理这个...... 非常感谢任何帮助。

【问题讨论】:

  • 这不是 PHP/C/Java!您不必传递变量。它们将始终通过范围查找链可用...只需在范围的顶层声明一次(就像您现在拥有的那样),然后您可以从这些函数内部访问它们。 不需要把它们从兔子洞里传下去!!
  • 嗯...如果是这种情况,那为什么我的变量未定义?绑定/柯里化的原因是什么,请参阅下面的@Raynos 答案
  • 迟到总比不到好:您的 userBid 定义正确,应该可以在您的查询中访问。它是在您的函数之外定义的,因此将在下面的函数内部可见。只要确保变量实际上定义正确并且 tag.user 没有未定义。一个简单的 console.log(userBid) 应该可以解决这个问题。

标签: javascript node.js callback scope mongoose


【解决方案1】:
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 将变量绑定到函数。

例如,我们通过以下方式将userAName 变量柯化到匿名函数中

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

}).bind(null, userAName));

【讨论】:

  • 感谢您的回答,我对此部分感到困惑:(function(userAName, err, userB) { 我担心看到此回调被第三方 (mongoose) 触发,我不能只对 @987654327 @ in,我的印象是第一个参数是 err ... 或者按照您的建议进行操作是否安全?
  • @Christopher 这就是.bind 的工作方式。它返回一个锁定第一个参数的新函数,并将其余参数放在第一个参数之后
猜你喜欢
  • 2014-06-17
  • 2020-02-07
  • 2012-12-23
  • 2011-05-10
  • 2011-07-07
  • 2012-05-03
相关资源
最近更新 更多