Talvez esteja faltando algo “simples”, situações “cotidianas”, ou sei lá oque.

Estou vendo muitas pessoas no fórum com a mesma dúvida: “usar o objeto Deferred do jQuery”, “pegar o retorno de uma requisição ajax”, e coisas relacionadas.

Eu sempre indico o ótimo tutorial do Maujor:

http://www.maujor.com/blog/2011/02/01/o-objeto-deferred-da-jquery-1-5, porém talvez por ser tão completo, e ter tantas informações, alguns iniciantes podem não estar “entendendo”.

Vou deixar alguns exemplos práticos(todos com o mesmo resultado), de algumas formas de usar o Deferred:

<html>
<head>
  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
  <script type="text/javascript">
  jQuery(document).ready(function(){
    /* retorna undefined */
    jQuery('#ajax_form_undefined').submit(function(){
      var form = jQuery( this );
      var ret = envia_form_nao_funciona( form );
      alert( ret );
      return false;
    });
    
    /* enviando ajax_form com done */
    jQuery('#ajax_form').submit(function(){

      var ret = envia_form( jQuery( this ) );
      ret.done(function( dados ){
        alert( dados );
      });
      
      return false;
    });
    
    /* enviando ajax_form2 com then */
    jQuery('#ajax_form2').submit(function(){

      var ret = envia_form( jQuery( this ) );
      ret.then(function( dados ){
        alert( dados );
      });
      
      return false;
    });
    
    /* enviando ajax_form3 com success */
    jQuery('#ajax_form3').submit(function(){

      var ret = envia_form( jQuery( this ) );
      ret.success(function( dados ){
        alert( dados );
      });
      
      return false;
    });
  });
  function envia_form_nao_funciona( form )
  {
    jQuery.ajax({
      type: form.attr('method'),
      url: form.attr('action'),
      data: form.serialize(),
      success: function( dados ){
        return dados 
      }
    });    
  }
  function envia_form( form )
  {
    return jQuery.ajax({
      type: form.attr('method'),
      url: form.attr('action'),
      data: form.serialize()
    });    
  }
  </script>
</head>
<body>
  <h2>Exemplo do que "não funciona"(retorna undefined)</h2>
  <form method="post" action="processa.php" id="ajax_form_undefined">
    <label><input type="hidden" name="id" value="" /></label>
    <label>Nome: <input type="text" name="nome" value="nome1" /></label>
    <label>Email: <input type="text" name="email" value="email1" /></label>

    <label><input type="submit" name="enviar" value="Enviar" /></label>
  </form>
  
  <h2>Recebendo com done</h2>
  <form method="post" action="processa.php" id="ajax_form">
    <label><input type="hidden" name="id" value="" /></label>
    <label>Nome: <input type="text" name="nome" value="nome2" /></label>
    <label>Email: <input type="text" name="email" value="email2" /></label>

    <label><input type="submit" name="enviar" value="Enviar" /></label>
  </form>
  
  <h2>Recebendo com then</h2>
  <form method="post" action="processa.php" id="ajax_form2">
    <label><input type="hidden" name="id" value="" /></label>
    <label>Nome: <input type="text" name="nome" value="nome3" /></label>
    <label>Email: <input type="text" name="email" value="email3" /></label>

    <label><input type="submit" name="enviar" value="Enviar" /></label>
  </form>

  <h2>Recebendo com success</h2>  
  <form method="post" action="processa.php" id="ajax_form3">
    <label><input type="hidden" name="id" value="" /></label>
    <label>Nome: <input type="text" name="nome" value="nome4" /></label>
    <label>Email: <input type="text" name="email" value="email4" /></label>

    <label><input type="submit" name="enviar" value="Enviar" /></label>
  </form>
</body>
</html>

Demonstração online

Convém lembrar que “precisamos” do deferred por causa do assincronismo das requisições, ou seja, o objeto ajax, envia para o servidor, o servidor processa, e o objeto ajax trás o retorno, sem refresh, porém também, sem que o restante do script aguarde esse retorno.

É essa diferença entre “sincrono” e “assincrono”. Note que enviando em modo sincrono async: false,, eu consigo “pegar o retorno” do ajax.

jQuery(document).ready(function(){
    /* retorna undefined */
    jQuery('#ajax_form_sincrono').submit(function(){
      var form = jQuery( this );
      var ret = envia_form_sincrono( form );
      alert( ret );
      return false;
    });

  });
  function envia_form_sincrono( form )
  {
    var ret = '';
    jQuery.ajax({
      type: form.attr('method'),
      url: form.attr('action'),
      data: form.serialize(),
      async: false,
      success: function( dados ){
        ret = dados;
      }
    });
    return ret;
  }

E ai ? qual dos dois usar ? sincrono ? ou assincrono com o deffered ?

Não sei, isso depende da sua aplicação, e é assunto para um próximo post talvez.

Usou ? comente.. este é o “meu pagamento” pelo que escrevo: o teu comentário.