1

Estoy usando el plugin FormValidation y AJAX y tengo un input que quiero validar cada vez que el usuario vaya escribiendo. La validación chequea que no se encuentre en la base de datos, pero el sistema se ralentiza.

Noté que lo que ocasiona que sea lento es: async: false, lo uso para que AJAX me devuelva un boolean. Si yo elimino async: false funciona sin relentizar pero no me devuelve el boolean correcto.

Acá el código de ajax:

function comprobacion(valor){
    var exists = false;
    $.ajax({
        type: 'post',
        url: 'cargos/comprobacion',
        async: false,
        data: {
            'valor': valor
        },
        success: function(data) {
            console.log(data);
            if(data){
                exists = true;
            }else{
                exists = false;
            }
        }
    });
    return exists;
}

Y acá el código de la validación:

if(comprobacion(value)){
    return {
        valid: false, //si encontro un registro en la BD
        message: 'El Cargo ya esta registrado'
    }
}else{
    return {
        valid: true, //sino encontro nada
        message: 'Correcto'
    }
}

Además del ralentizarme la web, me manda la siguiente advertencia (en la consola):

Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.

¿Por qué al validar usando un plugin y AJAX me relentiza la el sistema y me envía una advertencia que no había visto? ¿Qué puedo hacer para solucionar el problema?

Alvaro Montoro
  • 48,157
  • 26
  • 100
  • 179
bypabloc_
  • 2,346
  • 12
  • 35
  • 89

2 Answers2

2

La advertencia te explica cuál es el problema y por qué no deberías usar peticiones AJAX de manera síncrona como la estás haciendo. La traducción del mensaje:

Usar XMLHttpRequest en el hilo principal está obsoleto por los efectos negativos a la experiencia de usuario. Para más ayuda, comprueba https://xhr.spec.whatwg.org/.

Tu sistema se ralentiza porque estás realizando las llamadas asíncronas de manera síncrona (si suena como una contradicción es porque lo es). Es decir, cuando realizas peticiones, el sistema no se sigue ejecutando hasta que no se obtiene un respuesta, quedándose "colgado" mientras tanto.

Esto causa la mala experiencia de usuario que estás sufriendo, y es por lo que se considera una práctica obsoleta. Las peticiones asíncronas deben ser, como su propio nombre indica, asíncronas.


El problema que se te presenta al realizar la llamada de manera asíncrona es que la variable que se devuelve no es la correcta. Es decir, cuando la devuelves aún no se ha recibido la respuesta AJAX, por lo que se devolverá siempre su valor por defecto (en este caso, false).

La solución sería usar Promesas o mover el código que tiene que operar con el resultado de la llamada AJAX (es decir, el que recibe el valor de exists) a su propia función, y llamar a esa función desde el success. De este modo te asegurarás que ya tienes el valor cuando se ejecute ese código.


Para obtener ejemplos de cómo se haría lo que te comento, puedes mirar las respuestas a estas preguntas:

Alvaro Montoro
  • 48,157
  • 26
  • 100
  • 179
  • Me funciono correctamente y comprendí un poco mas la función del ajax. Es un poco confuso pero si se comprende. Mil gracias. – bypabloc_ Nov 25 '16 at 06:22
1

Eso me pasaba a mi y como te dijeron es por hacer llamadas asíncronas de manera síncrona. Así que si usas:

$.ajax({
    type: 'post',

debes eliminar

async: false,

async: false se usa con

$.ajax({
    type: 'get',

Espero que les sea de ayuda

TecniDEV
  • 11
  • 4