2009-04-16 7 views
197

Ich habe eine serverseitige Funktion, die Anmeldung erfordert. Wenn der Benutzer angemeldet ist, gibt die Funktion bei Erfolg 1 zurück. Wenn nicht, gibt die Funktion die Login-Seite zurück.Wie lasse ich jQuery warten, bis ein Ajax-Aufruf beendet ist, bevor er zurückkehrt?

Ich möchte die Funktion mit Ajax und jQuery aufrufen. Was ich tue, ist die Anfrage mit einem gewöhnlichen Link zu senden, mit einer Klick-Funktion. Wenn der Benutzer nicht angemeldet ist oder die Funktion fehlschlägt, möchte ich, dass der Ajax-Aufruf true zurückgibt, so dass die href ausgelöst wird.

Wenn ich jedoch den folgenden Code verwende, wird die Funktion beendet, bevor der Ajax-Aufruf ausgeführt wird.

Wie kann ich den Benutzer anmutig auf die Login-Seite umleiten?

$(".my_link").click(
    function(){ 
    $.ajax({ 
     url: $(this).attr('href'), 
     type: 'GET', 
     cache: false, 
     timeout: 30000, 
     error: function(){ 
      return true; 
     }, 
     success: function(msg){ 
      if (parseFloat(msg)){ 
       return false; 
      } else { 
       return true; 
      } 
     } 
    }); 
}); 
+1

Könnte ein alter Thread sein, aber wie @kofifus zeigt Einstellung a sync to false ist ein schlechtes Design und "keine Timeouts usw. werden verarbeitet". Könnte versuchen, diese vereinfachte Lösung - https: // stackoverflow.com/a/11576418/6937841 – Shan

Antwort

295

Wenn Sie die $.ajax() Funktion nicht wollen sofort zurückkehren, stellen Sie die async Option false:

$(".my_link").click(
    function(){ 
    $.ajax({ 
     url: $(this).attr('href'), 
     type: 'GET', 
     async: false, 
     cache: false, 
     timeout: 30000, 
     error: function(){ 
      return true; 
     }, 
     success: function(msg){ 
      if (parseFloat(msg)){ 
       return false; 
      } else { 
       return true; 
      } 
     } 
    }); 
}); 

Aber ich möchte darauf hinweisen, dass dies auf den Punkt von AJAX Zähler wäre. Außerdem sollten Sie die Antwort in den Funktionen error und success verarbeiten. Diese Funktionen werden nur aufgerufen, wenn die Antwort vom Server empfangen wird.

+1

Sie meinen falsch :) Ich denke? – veggerby

+0

Hah! Ja dank. – cgp

+9

Das Weiterleiten von guten Praktiken ist meiner Meinung nach nicht zu beurteilen, und es gibt einige der besten Antworten auf StackOverflow. – semperos

27

Das zugrunde liegende XMLHttpRequest-Objekt (das von jQuery zum Ausführen der Anforderung verwendet wird) unterstützt die asynchrone -Eigenschaft. Setzen Sie es auf false. Wie

async: false 
9

denke ich, es würde einfacher sein, wenn Sie Ihre success Funktion codieren die entsprechende Seite zu laden, anstatt true oder false zurück.

Zum Beispiel statt der Rückkehr true Sie tun können:

window.location="appropriate page"; 

auf diese Weise, wenn die Erfolgsfunktion die Seite umgeleitet wird aufgerufen wird.

30

ich nicht $.ajax verwenden aber die $.post und $.get Funktionen, so dass, wenn ich auf die Antwort warten müssen, ich benutze diese:

$.ajaxSetup({async: false}); 
$.get("..."); 
+0

Dies funktioniert für $ .getJSON() als auch ... was Sinn macht –

17

Statt async auf false der Einstellung, die sind in der Regel schlecht Design, Sie Möglicherweise möchten Sie die UI blockieren, während der Vorgang aussteht.

Dies kann gut mit jQuery erreicht werden verspricht wie folgt:

// same as $.ajax but settings can have a maskUI property 
// if settings.maskUI==true, the UI will be blocked while ajax in progress 
// if settings.maskUI is other than true, it's value will be used as the color value while bloking (i.e settings.maskUI='rgba(176,176,176,0.7)' 
// in addition an hourglass is displayed while ajax in progress 
function ajaxMaskUI(settings) { 
    function maskPageOn(color) { // color can be ie. 'rgba(176,176,176,0.7)' or 'transparent' 
     var div = $('#maskPageDiv'); 
     if (div.length === 0) { 
      $(document.body).append('<div id="maskPageDiv" style="position:fixed;width:100%;height:100%;left:0;top:0;display:none"></div>'); // create it 
      div = $('#maskPageDiv'); 
     } 
     if (div.length !== 0) { 
      div[0].style.zIndex = 2147483647; 
      div[0].style.backgroundColor=color; 
      div[0].style.display = 'inline'; 
     } 
    } 
    function maskPageOff() { 
     var div = $('#maskPageDiv'); 
     if (div.length !== 0) { 
      div[0].style.display = 'none'; 
      div[0].style.zIndex = 'auto'; 
     } 
    } 
    function hourglassOn() { 
     if ($('style:contains("html.hourGlass")').length < 1) $('<style>').text('html.hourGlass, html.hourGlass * { cursor: wait !important; }').appendTo('head'); 
     $('html').addClass('hourGlass'); 
    } 
    function hourglassOff() { 
     $('html').removeClass('hourGlass'); 
    } 

    if (settings.maskUI===true) settings.maskUI='transparent'; 

    if (!!settings.maskUI) { 
     maskPageOn(settings.maskUI); 
     hourglassOn(); 
    } 

    var dfd = new $.Deferred(); 
    $.ajax(settings) 
     .fail(function(jqXHR, textStatus, errorThrown) { 
      if (!!settings.maskUI) { 
       maskPageOff(); 
       hourglassOff(); 
      } 
      dfd.reject(jqXHR, textStatus, errorThrown); 
     }).done(function(data, textStatus, jqXHR) { 
      if (!!settings.maskUI) { 
       maskPageOff(); 
       hourglassOff(); 
      } 
      dfd.resolve(data, textStatus, jqXHR); 
     }); 

    return dfd.promise(); 
} 

mit diesem können Sie jetzt tun:

ajaxMaskUI({ 
    url: url, 
    maskUI: true // or try for example 'rgba(176,176,176,0.7)' 
}).fail(function (jqXHR, textStatus, errorThrown) { 
    console.log('error ' + textStatus); 
}).done(function (data, textStatus, jqXHR) { 
    console.log('success ' + JSON.stringify(data)); 
}); 

Und die UI wird, bis die Ajax-Befehl gibt blockieren

siehe jsfiddle

+0

Wird async nicht auf false gesetzt, wird genau das gleiche mit Ausnahme einer einzigen Zeile gemacht – Vincent

+3

Überhaupt nicht async auf false stellen Sie die async-Anforderung ein, dh die Verarbeitung wird angehalten, bis sie zurückkehrt, was z kein E Lüftungen, andere Ajax-Anfragen, Timeouts usw. werden bearbeitet. Sie können den obigen Code auch ändern, um nur einen Teil der Benutzeroberfläche zu blockieren, während Ihr Ajax verarbeitet (dh der Teil, auf den es sich auswirkt). – kofifus

Verwandte Themen