2011-09-01 6 views
1

Je rencontre des problèmes avec la portée variable avec une application Node.js que je fais, je comprends généralement comment la portée variable fonctionne dans/autour d'une fonction (dans ce cas, les fonctions de rappel anonymes).Gestion des variables via une variable dans Javascript

Ce que je combats est quelle est la meilleure façon de maintenir vairables à travers une chaîne/trou de callbacks anonymes. Là où normalement je pourrais passer les variables aux fonctions, mais parce que j'utilise mongoose (mongodb ORM) je ne peux pas passer mes propres variables dans. Et donc devoir soit recourir à définir les variables encore et encore à chaque étape plus profond dans le rappeler.

Quelle est la meilleure façon de procéder?

Ci-dessous mon code où je finis par des variables non définies obtenir le temps que je veux les utiliser pour 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); 
      } 
     }); 
     } 
    }); 
    } 
}); 

Certes, il y a une meilleure façon de gérer cette ... est beaucoup d'aide apprécié.

+1

Ce n'est pas PHP/C/Java! Vous n'avez pas besoin de transmettre vos variables. Ils seront toujours disponibles via la chaîne de recherche de portée ... Il suffit de les déclarer une fois au niveau supérieur de votre portée (comme vous l'avez maintenant), et vous pouvez ensuite y accéder à partir de ces fonctions. ** Pas besoin de les faire descendre dans le trou du lapin !! ** –

+0

Euh ... si c'était le cas, alors pourquoi mes variables étaient-elles indéfinies? Et quelle serait la raison pour bind/currying voir la réponse @Raynos ci-dessous – Christopher

+0

Mieux vaut tard que jamais: Votre userBid est défini correctement et devrait être accessible à l'intérieur de votre requête. Il est défini en dehors de votre fonction et sera donc visible à l'intérieur de votre fonction ci-dessous. Assurez-vous simplement que la variable est correctement définie et que tag.user n'est pas indéfini. Un simple fichier console.log (userBid) devrait résoudre cette question. – Jorre

Répondre

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

Soit l'utilisation étendue de fermeture (tag.user est disponible par le biais de fermetures) ou utiliser .bind pour lier des variables à une fonction.

Par exemple, nous avons cari la variable userAName dans la fonction anonyme en faisant

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

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

Merci pour votre réponse, je suis confus au sujet de cette section: '(function (userAName, err, userB) {' Je suis inquiet de voir que ce callback est déclenché par un tiers (mongoose), je ne peux pas juste inters 'userAName' in, j'ai eu l'impression que le 1er argument est' err' ... Ou est-ce que c'est sûr de faire ce que vous avez suggéré? – Christopher

+0

@Christopher c'est comme ça que '.bind' fonctionne.Il retourne une nouvelle fonction avec le premier argument verrouillé et place le reste des arguments après le premier argument – Raynos

+0

Brilliant! – Christopher

Questions connexes