jquery NO SIEMPRE espera hasta el valor devuelto, pero a veces lo hace

He visto numerosos ejemplos aquí y he intentado durante horas hacer que funcionen, pero parece que no puedo darme cuenta de lo que estoy haciendo mal. Soy muy nuevo en jquery y ajax, así que sé amable.

Estoy intentando usar el complemento jquery de smartWizard. Aquí hay un código

            function validateStep1()
            {
                var isValid = true;


                // validate first_name
                var first_name = $('#first_name').val();
                if(!first_name && first_name.length <= 0)
                {
                    isValid = false;
                    $('#msg_first_name').html('<?php echo $LANG['field_this_required'] ?>').show();
                }
                else
                {
                    $('#msg_first_name').html('').hide();
                }

                // validate last_name
                var last_name = $('#last_name').val();
                if(!last_name && last_name.length <= 0)
                {
                    isValid = false;
                    $('#msg_last_name').html('<?php echo $LANG['field_this_required'] ?>').show();
                }
                else
                {
                    $('#msg_last_name').html('').hide();
                }

                // validate address
                var address = $('#address').val();
                if(!address && address.length <= 0)
                {
                    isValid = false;
                    $('#msg_address').html('<?php echo $LANG['field_this_required'] ?>').show();
                }
                else
                {
                    $('#msg_address').html('').hide();
                }

                // validate city
                var city = $('#city').val();
                if(!city && city.length <= 0)
                {
                    isValid = false;
                    $('#msg_city').html('<?php echo $LANG['field_this_required'] ?>').show();
                }
                else
                {
                    $('#msg_city').html('').hide();
                }

                // validate county
                /*
                var county = $('#county').val();
                if(!county && county.length <= 0)
                {
                    isValid = false;
                    $('#msg_county').html('<?php echo $LANG['field_this_required'] ?>').show();
                }
                else
                {
                    $('#msg_county').html('').hide();
                }
                */

                // validate state
                var state = $('#state').val();
                if(!state && state.length <= 0)
                {
                    isValid = false;
                    $('#msg_state').html('<?php echo $LANG['field_this_required'] ?>').show();
                }
                else
                {
                    $('#msg_state').html('').hide();
                }

                // validate postal
                var postal = $('#postal').val();
                if(!postal && postal.length <= 0)
                {
                    isValid = false;
                    $('#msg_postal').html('<?php echo $LANG['field_this_required'] ?>').show();
                }
                else
                {
                    $('#msg_postal').html('').hide();
                }

                // validate home_phone
                var home_phone = $('#home_phone').val();
                if(!home_phone && home_phone.length <= 0)
                {
                    isValid = false;
                    $('#msg_home_phone').html('<?php echo $LANG['field_this_required'] ?>').show();
                }
                else
                {
                    $('#msg_home_phone').html('').hide();
                }


            if(isValid==true)
            {
                document.getElementById('step_num').value=1;

                loading('<?php echo $LANG['saving']; ?> ',1);

                $.post('editprofile.php',$('#editProfile').serialize(),function(data)
                {
                    unloading();
                    if(!data)
                    {
                        isValid = false;
                        $('#msg_step-1').html("<p style='font-weight:bold;color:#ff0000'><?php echo $LANG['database_update_error']; ?></p>").show();
                    }
                    else if(data.status !=1 )
                    {
                        isValid = false;
        alert(data.message);
                        $('#msg_step-1').html("<p style='font-weight:bold;color:#ff0000'>"+data.message+"</p>").show();
                    }
                    else
                    {
                        $('#msg_step-1').html("<p style='font-weight:bold;color:#ff0000'>"+data.message+"</p>").show();
                        isValid = true;
                    }

                },'json')
                .done(function() { alert("done "+isValid); return isValid;})
                .fail(function() { alert("fail "+isValid); return isValid;})
                ;
            }
            else
            {
                return isValid;
            }
          //Commented out the return so that it will only return when done above.
          //return isValid;
        }

Hay otro código que comprueba el valor de retorno de esta función y actúa en consecuencia. Si alguna de las comprobaciones de validación iniciales falla, el otro código no se ejecuta porque la variable isValid se establece en falso y eso es lo que se devuelve. Mi problema es con la publicación en editprofile.php: el código continúa como si la función hubiera devuelto un valor verdadero aunque aún no haya devuelto nada. Todavía continúa ejecutando el código en $.post pero solo después de que se haya ejecutado otro código fuera de esta función.

Entiendo que el código se ejecuta de forma asíncrona; sin embargo, estoy confundido en cuanto a por qué SIN EXCEPCIÓN siempre obtiene el false valor cuando cualquiera de los cheques para cosas como $('#address').val() devolver un valor falso; sin embargo, no lo obtiene de la $.post código. ¿Por qué esperar a que todos devuelvan un valor pero no esperar a que el $.post código?

También estoy confundido sobre cómo puede actuar el código de llamada antes de que se devuelva un valor.

Solo por el bien de la documentación, aquí está el código que llama a esa función:

          function leaveAStepCallback(obj){
                var step_num= obj.attr('rel');
                return validateSteps(step_num);
          }

            function validateSteps(step)
            {
                var isStepValid = true;
                  // validate step 1
                  if(step == 1){
                        if(validateStep1() == false ){
                          isStepValid = false; 
                          $('#wizardvalidate').smartWizard('showMessage','Please correct the errors in step'+step+ ' and click next.');
                          $('#wizardvalidate').smartWizard('setError',{stepnum:step,iserror:true});         
                        }else{
                          $('#wizardvalidate').smartWizard('setError',{stepnum:step,iserror:false});
                        }
                  }

                  // validate step 2
                  if(step == 2){
                        if(validateStep2() == false ){
                          isStepValid = false; 
                          $('#wizardvalidate').smartWizard('showMessage','Please correct the errors in step'+step+ ' and click next.');
                          $('#wizardvalidate').smartWizard('setError',{stepnum:step,iserror:true});         
                        }else{
                          $('#wizardvalidate').smartWizard('setError',{stepnum:step,iserror:false});
                        }
                  }

                  // validate step3
                  if(step == 3){
                        if(validateStep3() == false ){
                          isStepValid = false; 
                          $('#wizardvalidate').smartWizard('showMessage','Please correct the errors in step'+step+ ' and click next.');
                          $('#wizardvalidate').smartWizard('setError',{stepnum:step,iserror:true});         
                        }else{
                          $('#wizardvalidate').smartWizard('setError',{stepnum:step,iserror:false});
                        }
                  }

          return isStepValid;
        }

Una vez más, soy nuevo en todo esto, ¡así que por favor sean amables! :)

preguntado el 08 de marzo de 13 a las 21:03

En realidad, jquery NUNCA espera el valor devuelto de una solicitud ajax a menos que lo haga sincrónico. Tus alertas te están confundiendo. No puede regresar de las propiedades de devolución de llamada de una solicitud ajax, no hace nada. -

Porque tienes llamadas AJAX solo cuando isValid es verdad. Cuando es falso va directo al return isValid (y isValid === false). Utilizando return in .done() y .fail() no haga nada: está volviendo de las funciones anónimas, no de la validateStep1() función. -

A jax. Además, en general, por favor incluya la mínimo cantidad de código necesaria para demostrar el problema; de lo contrario, se necesita bastante tiempo para determinar dónde está el código en cuestión. -

2 Respuestas

Como dijiste en tu pregunta, $.post is asincrónico.

Su devolución de llamada solo se ejecutará cuando el servidor responda, lo que se garantiza que será un tiempo después de que el resto de su código termine de ejecutarse.

respondido 08 mar '13, 21:03

Estaba enfrentando el mismo problema y lo resolví después de algunas horas de tirarme del pelo...

var stpflag = falso;

function validateSteps(step){
    var isStepValid = true;
    // validate step 1
    if(step == 1){
        var returnstatus = savefunctionality();
        if((returnstatus ==  false ) && (stpflag== false)){
            isStepValid = false; 
            $('#wizard').smartWizard('showMessage','Please correct the errors in step'+step+ ' and click next.');
            $('#wizard').smartWizard('setError',{stepnum:step,iserror:true}); 
            // $('#wizard').smartWizard.prototype.goBackward();
        }else if((returnstatus ==  false ) && (stpflag== true)){
            isStepValid = true;
            $('#wizard').smartWizard('setError',{stepnum:step,iserror:false});
             $('#wizard').smartWizard('hideMessage','');
            showstep2(); // here write your logic for render next page on step-2 div.
            stpflag=false;
        }
    }
  return isStepValid;
}

función guardarfuncionalidad() {

    var returnVal = false;

$.ajax(

{

        type: 'POST',

        dataType: 'json',

        url: '/mainfolder/folder/savepage/',

        async: true,


        data:  values,                  

        success: function(json) {
            $("#error_msg").html("");
            if(json.result.errors != undefined){
                if(json.result.errors.length > 0){
                    itemData = json.result.errors;
         returnVal = false;
                    stpflag = false;

                } 
            } else if(json.result == 1){
                returnVal = true;
                stpflag = true;
                $('a.buttonNext').trigger('click');
            }
        }
    });
    return returnVal;
}

Aquí he usado dos variables 1. returnVal: siempre devuelve falso 2. stpflag: creó una nueva variable global stpflag.

activó el botón siguiente explícitamente.

Espero que funcione para usted también

contestado el 22 de mayo de 13 a las 08:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.