2009-09-22 10 views
34

Comment mettre à jour la variable returnHtml à partir de la fonction de succès anonyme?jQuery Ajax succès fonction anonyme portée

function getPrice(productId, storeId) { 
    var returnHtml = ''; 

    jQuery.ajax({ 
     url: "/includes/unit.jsp?" + params, 
     cache: false, 
     dataType: "html", 
     success: function(html){ 
      returnHtml = html; 
     } 
    }); 

    return returnHtml; 
} 

Répondre

54

C'est la mauvaise approche. Le premier A dans AJAX est Asynchrone. Cette fonction retourne avant que l'appel AJAX retourne (ou au moins il peut). Ce n'est donc pas une question de portée. C'est une question de commande. Il y a seulement deux options:

  1. Vérifiez la synchronisation des appels AJAX (pas recommandé) avec l'option async: false; ou
  2. Changez votre façon de penser. Au lieu de renvoyer le code HTML de la fonction, vous devez passer un rappel pour être appelé lorsque l'appel AJAX réussit.

À titre d'exemple (2):

function findPrice(productId, storeId, callback) { 
    jQuery.ajax({ 
     url: "/includes/unit.jsp?" + params, 
     cache: false, 
     dataType: "html", 
     success: function(html) { 
      callback(productId, storeId, html); 
     } 
    }); 
} 

function receivePrice(productId, storeId, html) { 
    alert("Product " + productId + " for storeId " + storeId + " received HTML " + html); 
} 

findPrice(23, 334, receive_price); 
+1

Gotchya - je me suis dit que je dois faire. mais si je devais le faire? –

+0

Il est difficile de répondre à cette question sans savoir comment vous avez l'intention d'utiliser la méthode getPrice(). À quoi sert-il? Comment est-ce utilisé? C'est le code à ce niveau "externe" qui devra être ajusté. – cletus

+0

Ok je l'ai eu. Je ne me suis pas rendu compte que productId et storeId seraient dans la portée et que je peux réellement passer ce genre de choses dans le rappel. –

11

Votre fonction anonyme il fait ont accès à la variable returnHtml dans son champ d'application, et donc le code, il travaille en fait que vous le attendre. Où vous allez probablement mal est dans votre déclaration de retour.

Rappelez-vous que la A dans AJAX est synonyme de asynchronous, ce qui signifie qu'il ne se produit pas en même temps. Pour cette raison, la ligne returnHtml = html se passe réellement après vous appelez return returnHtml;, donc returnHtml est toujours une chaîne vide.

Il est difficile de dire ce que vous devez faire pour obtenir ce travail que vous voulez sans voir le reste de votre code, mais ce que vous pouvez faire est d'ajouter un autre rappel à la fonction:

function getPrice(productId, storeId, callback) { 
    jQuery.ajax({ 
     url: "/includes/unit.jsp?" + params, 
     cache: false, 
     dataType: "html", 
     success: callback 
    }); 
} 

getPrice(5, 1, function(html) { 
    alert(html); 
}); 
13

Réponse courte, vous ne pouvez pas, le premier A dans AJAX signifie Asynchrone, ce qui signifie que la requête continue quand vous arrivez à l'instruction return.

Vous peut le faire avec synchrone (non-async) demande, mais il est généralement une mauvaise chose

Quelque chose comme ce qui suit oughta renvoyer les données.

function getPrice(productId, storeId) { 
    var returnHtml = ''; 

    jQuery.ajax({ 
    url: "/includes/unit.jsp?" + params, 
    async: false, 
    cache: false, 
    dataType: "html", 
    success: function(html){ 
     returnHtml = html; 
    } 
    }); 

    return returnHtml; 
} 

MAIS

À moins que vous avez vraiment vraiment besoin d'être en mesure d'utiliser immédiatement la valeur de retour de test, vous serez beaucoup mieux passer un rappel en test. Quelque chose comme

function getPrice(productId, storeId, callback) { 
    jQuery.ajax({ 
    url: "/includes/unit.jsp?" + params, 
    async: true, 
    cache: false, 
    dataType: "html", 
    success: function(html){ 
     callback(html); 
    } 
    }); 
} 

//the you call it like 
getPrice(x,y, function(html) { 
    // do something with the html 
} 

Modifier Sheesh, les gars vous êtes plus rapide de dire ce que je disais :-)

+0

Le réglage du rendu de la page de blocage 'async: false' sera-t-il effectué par le navigateur? –

+0

@Ramswaroop Je crois, oui –

Questions connexes