javascript - procesando - ¿Por qué mi spinner GIF se detiene mientras se está ejecutando la llamada jQuery ajax?
mostrar loading mientras carga pagina ajax (12)
- Los navegadores son de subproceso único y multiproceso. Para cualquier navegador:
Cuando una llamada función contiene una función ajax anidada, // aquí el código java / servlet / jsp pone el código Thread.sleep (5000); en servlet para comprender la asincronía en ajax cuando es verdadero o falso.
function ajaxFn(){ $(''#status'').html(''WAIT... <img id="theImg" src="page-loader.gif" alt="preload" width="30" height="30"/>''); $(''#status'').css("color","red"); $.ajax({ url:"MyServlet", method: "POST", data: { name: $("textarea").val(), id : $("input[type=text]").val() }, //async: false, success:function(response){ //alert(response); //response is "welcome to.." $("#status").text(response); }, complete:function(x,y){ //alert(y) }, error:function(){ $("#status").text("?"); } }); $(''#status'').css("color","green");
}
Async: verdadero para navegadores de una sola hebra para que dom se cargue inmediatamente. Y no pongas el objetivo dom dentro del éxito, porque la función de éxito espera hasta la respuesta. Hasta ese momento tu dom no recibirá carga.
Estoy empezando a destetarme de los paneles de actualización de ASP.NET. Estoy usando jQuery y jTemplates para vincular los resultados de un servicio web a una grilla, y todo funciona bien.
Aquí está el problema: estoy tratando de mostrar un GIF giratorio mientras se actualiza la tabla (al igual que UpdateProgress en ASP.NET). Lo tengo todo funcionando, excepto que el spinner está congelado. Para ver qué está pasando, he intentado mover el spinner desde el divisor de progreso de actualización y hacia fuera en la página donde puedo verlo todo el tiempo. Gira y gira hasta que se inicia la actualización, y se mantiene congelado hasta que finaliza la actualización, y luego comienza a girar nuevamente. No es realmente lo que quieres de un spinner ''por favor espera''!
Esto está en IE7, todavía no hemos tenido la oportunidad de probar en otros navegadores. ¿Alguna idea? ¿La llamada ajax o la vinculación de datos del lado del cliente requieren tantos recursos que el navegador no puede atender sus GIF animados?
Actualizar
Aquí está el código que refresca la grilla. No estoy seguro de si esto es síncrono o asíncrono.
updateConcessions = function(e) {
$.ajax({
type: "POST",
url: "Concessions.aspx/GetConcessions",
data: "{''Countries'':''ga''}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
applyTemplate(msg);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
}
});
}
applyTemplate = function(msg) {
$(''div#TemplateTarget'').setTemplate($(''div#TemplateSource'').html());
$(''div#TemplateTarget'').processTemplate(msg);
}
Actualización 2
Acabo de consultar la documentación de jQuery y el método $.ajax()
es asíncrono de manera predeterminada. Solo por las patadas, agregué esto
$.ajax({
async: true,
...
y no hizo ninguna diferencia.
¿Estás haciendo una llamada síncrona o llamada asíncrona? las llamadas sincrónicas causan que el navegador aparentemente se bloquee durante la duración de la llamada. La otra posibilidad es que el sistema esté muy ocupado haciendo cualquier trabajo que esté haciendo.
¿Estás seguro de que durante la llamada AJAX el GIF no está girando?
En sus concesiones.aspx ponga esta línea en algún lugar del manejo de GetConcessions: -
System.Threading.Thread.Sleep(5000);
Sospecho que el gif gira durante 5 segundos y luego se congela, mientras que IE renderiza y pinta el resultado.
Envolver la llamada ajax en la función setTimeout me ayudó a evitar la congelación de gif-animation:
setTimeout(function() {
$.get(''/some_link'', function (response) {
// some actions
});
}, 0);
He visto este comportamiento en el pasado al hacer llamadas AJAX. Creo que esto está relacionado con el hecho de que los navegadores solo tienen un único subproceso, por lo que cuando se devuelve la llamada AJAX, el hilo funciona en la llamada, por lo que el GIF animado debe detenerse momentáneamente.
La imagen se congela porque, mientras está oculta, IE desactiva la animación.
Para solucionar esto, añada la imagen de carga en lugar de mostrarla:
function showLoader(callback){
$(''#wherever'').append(
''<img class="waiting" src="/path/to/gif.gif" />''
);
callback();
}
function finishForm(){
var passed = formValidate(document.forms.clientSupportReq);
if(passed)
{
$(''input#subm'')
.val(''Uploading...'')
.attr(''disabled'',''disabled'');
$(''input#res'').hide();
}
return passed;
}
$(function(){
// on submit
$(''form#formid'').submit(function(){
var l = showLoader( function(){
finishForm()
});
if(!l){
$(''.waiting'').remove();
}
return l;
});
});
La respuesta de dennismonsewicz es grandte. Utilice spin.js y el sitio http://fgnass.github.com/spin.js/ muestra el paso que es bastante fácil. En un proceso pesado, debemos usar animaciones CSS. No se deben usar animaciones y GIF controlados por JS, ya que el límite de un solo hilo de lo contrario la animación se congelará. Las animaciones CSS están separadas del subproceso UI.
No es la llamada de Ajax la que congela el navegador. Es el controlador de éxito (applyTemplate). Insertar HTML en un documento como ese puede congelar IE, dependiendo de la cantidad de HTML que haya. Es porque la interfaz de usuario de IE tiene un solo hilo; si lo nota, los menús IE actuales también se congelan mientras esto sucede.
Como prueba, intente:
applyTemplate = function(msg) {
return;
}
No recuerdo exactamente qué lo causó, pero tuvimos un problema similar con IE6 en una caja ocupada y lo arreglamos con este increíble hack en el Javascript:
setTimeout("document.images[''BusyImage''].src=document.images[''BusyImage''].src",10);
Eso simplemente establece la fuente de la imagen como lo era antes, pero aparentemente es suficiente para empujar a IE fuera de su estupor.
editar: creo que recuerdo lo que estaba causando esto: estábamos cargando la animación en un div con pantalla: ninguno. IE lo carga y no inicia la animación, porque está oculta. Lamentablemente, no se inicia la animación cuando configura el bloque que contiene para mostrar: bloque, por lo que usamos la línea de código anterior para engañar a IE y volver a cargar la imagen.
Sé que la pregunta era sobre llamadas ajax asincrónicas. Sin embargo, quería agregar que he encontrado lo siguiente en mis pruebas con respecto a las llamadas síncronas ajax:
Para llamadas ajax sincrónicas. Mientras la llamada está en progreso (es decir, esperando que el servidor responda). Para la prueba puse un retraso en la respuesta del servidor en el servidor.
Firefox 17.0.1: el gif animado continúa animándose correctamente.
Chrome v23: el gif animado detiene la animación mientras la solicitud está en progreso.
Tuve un problema similar con la congelación del navegador. Si está desarrollando y probando localmente, por alguna razón, congela el navegador web. Después de subir mi código a un servidor web, comenzó a funcionar. Espero que esto ayude, porque me llevó horas averiguarlo por mí mismo.
bueno, esto es por muchas razones. En primer lugar, cuando el ajax vuelva a llamar al servidor, detectará unos milisegundos de gif congelado, pero no muchos relevantes. Después de que comience a procesar información, y dependiendo de los objetos que manipule y cómo lo haga, tendrá más o menos tiempo para congelar su gif. Esto se debe a que el hilo está ocupado procesando información. Por ejemplo, si tienes 1000 objetos y haces un pedido, y mueves información, y también usas jquery y añades, insertas, $ .each comandos, sentirás un gif congelado. A veces es imposible evitar todos los gifs congelados, pero puedes limitar el tiempo a unos pocos milisegundos haciendo esto: Haz una lista de respuesta ajax, y trátala cada 2 segundos (con esto obtendrás los resultados en una única matriz y harás llámalo con un setInterval y evitas el cuello de botella de try process one response cuando la respuesta anterior aún está en proceso). si usa JQuery, no use $ .each, use for. No use dom manipulation (append, insert, etc.), use html (). En resumen, haga menos código, refactorice, y procese toda la respuesta (si hizo más de 1) como solo 1. Lo siento por mi inglés.