from - ¿Cómo hago que jQuery espere a que finalice una llamada Ajax antes de que regrese?
jquery change title page (5)
Creo que las cosas serían más fáciles si codificas tu función de success
para cargar la página apropiada en lugar de devolver true
o false
.
Por ejemplo, en lugar de devolver la true
, podrías hacer:
window.location="appropriate page";
De esa manera, cuando se llama la función de éxito, la página se redirige.
Tengo una función del lado del servidor que requiere inicio de sesión. Si el usuario ha iniciado sesión, la función devolverá 1 en caso de éxito. Si no, la función devolverá la página de inicio de sesión.
Quiero llamar a la función usando Ajax y jQuery. Lo que hago es enviar la solicitud con un enlace ordinario, con una función de clic aplicada. Si el usuario no ha iniciado sesión o la función falla, quiero que la llamada Ajax devuelva true, de modo que href se active.
Sin embargo, cuando uso el siguiente código, la función se cierra antes de que se realice la llamada Ajax.
¿Cómo puedo redirigir al usuario correctamente a la página de inicio de sesión?
$(".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;
}
}
});
});
El objeto XMLHttpRequest subyacente (utilizado por jQuery para realizar la solicitud) admite la propiedad asíncrona. Ponlo en falso . Me gusta
async: false
En lugar de establecer async en falso, que suele ser un mal diseño, es posible que desee considerar el bloqueo de la interfaz de usuario mientras la operación está pendiente.
Esto se puede lograr muy bien con las promesas de jQuery de la siguiente manera:
// 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();
}
Con esto ahora puedes hacer:
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));
});
Y la IU se bloqueará hasta que el comando ajax regrese
ver jsfiddle
No estoy usando $.ajax
sino las funciones $.post
y $.get
, así que si necesito esperar la respuesta, uso esto:
$.ajaxSetup({async: false});
$.get("...");
Si no desea que la función $.ajax()
regrese inmediatamente, configure la opción async
en 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;
}
}
});
});
Pero, me gustaría señalar que esto sería contrario al punto de AJAX. Además, debe manejar la respuesta en las funciones de error
y success
. Esas funciones solo se llamarán cuando la respuesta se reciba del servidor.