2009-10-30 4 views
3

J'essaie de travailler avec l'API Google Maps et j'ai des problèmes. J'ai créé une fonction appelée getPoint qui accepte une adresse. Il utilise l'API google pour transformer cette adresse en objet GPoint à l'aide de la fonction GClientGeocoder.getLatLng (adresse, rappel). Le getLatLng() est passé l'adresse et une fonction de rappel comme vous pouvez le voir ci-dessous. Je veux que la fonction getPoint() que j'ai écrite retourne la variable "point" passée à la fonction de rappel à partir de l'appel getLatLng(). J'ai du mal à comprendre comment faire cela ou même si cela peut être fait?Problème de valeur de retour de la fonction Javascript

function getPoint(address) { 
    var geocoder = new GClientGeocoder(); 

    return geocoder.getLatLng(
    address, 
    function(point){ 
     return point; 
    } 
); 
} 

Merci d'avance pour l'aide!

Répondre

6

GClientGeocoder.getLatLng est une déclaration opération asynchrone, de sorte que vous ne pouvez pas avoir un return dans getPoint ne fait ce que vous attendez.

Vous avez besoin de restructurer votre code pour prendre une fonction de rappel, que vous appelez lorsque l'opération asynchrone complète:

function getPoint(address, callback) { 
    var geocoder = new GClientGeocoder(); 

    geocoder.getLatLng(
     address, 
     function(point){ 
      /* asynch operation complete. 
      * Call the callback with the results */ 
      callback(point) 
     } 
    ); 
} 

ou encore mieux (même si une touche plus ésotérique):

function getPoint(address, callback) { 
    var geocoder = new GClientGeocoder(); 

    geocoder.getLatLng(
     address, 
     callback // GClientGeocoder will call the callback for you 
    ); 
} 

Modifier re votre commentaire question:

O K qui est une toute autre question, mais en quelques mots, le rappel de la fonction JavaScript que vous passez aura accès à votre instance de carte tant que vous définissez la fonction dans la même portée que l'instance de carte est définie:

var map = new GMap2(/*...*/); 
var addresses = []; // list of address strings 
for(var i=0; i < addresses.length; i++) { 
    getPoint(addresses[i], function(point) { // pass the callback function 
     map.addOverlay(/*...*/); // map variable is in scope 
    }) 
} 

Ce style de fonction est appelé une fermeture.

+0

Merci pour la grande réponse. Cela m'amène à un autre problème je pense ... J'ai une fonction appelée Initialize() qui s'appelle onLoad() du corps qui crée un objet GMap2. Je fais ensuite un post ajax pour récupérer une liste d'adresses et ensuite faire une boucle à travers ces adresses et créer un objet GPoint un par un afin que je puisse ajouter un GMarker au GMap2 pour chaque adresse. La fonction de rappel que vous dites que je devrais spécifier ne nécessite-t-elle pas l'accès à cet objet GMap? Si oui, comment puis-je obtenir cet objet GMap2 dans la portée de la fonction de rappel? – Ryan

+0

Peu importe, la carte est dans la portée pas comme je pensais que ce n'était pas. Merci! – Ryan

+2

Ah christ, je viens de taper une réponse entière à votre commentaire. –

0

Vous ne pouvez pas faire cela. getLatLng() est une fonction asynchrone: elle envoie une requête HTTP et appelle le rappel une fois qu'une réponse est reçue. Pendant ce temps, l'exécution de votre script local continuera et getLatLng() retournera avant que votre rappel ne soit appelé.

2

Non, cela ne peut pas être fait. Au lieu de cela, vous devez configurer une méthode qui sait quoi faire avec la réponse une fois qu'elle arrive à un moment donné dans le futur - c'est la nature d'un rappel.

Ainsi, actuellement, votre conception ressemble à:

var myPoint = getPoint(theAddress); 
doSomethingWithPoint(myPoint); 
doSomethingElseWithPoint(myPoint); 

Mais maintenant, il devrait ressembler

function getPoint(address, callback) { 
    var geocoder = new GClientGeocoder(); 
    geocoder.getLatLng(address, callback); 
} 
getPoint(theAddress, function(myPoint) { 
    doSomethingWithPoint(myPoint); 
    doSomethingElseWithPoint(myPoint); 
}); 
+0

+1; mais votre fonction de rappel anonyme nécessite un paramètre "myPoint". – RMorrisey

+0

D'oh! Merci. 15 caractères 15 caractères 15 caractères –

Questions connexes