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.