2011-09-01 90 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