Macarronada sabor ajax

Oi pessoal, tenho o seguinte problema. Imagine que tenho um algoritmo assim para implementar em javascript com ajax:

Ler um monte de dados. Enviar e/ou receber algo via ajax para o servidor. Processar a resposta ajax. Enviar e/ou alguma outra coisa para algum outro lugar do servidor. Fazer mais algum processmento. Enviar e/ou receber mais lgo do servidor. etc.
Tal como demonstrado no algoritmo, o processo parece bem simples. E de fato, implementar com ajax síncrono ficaria simples. No entanto ajax síncrono é coisa do capeta e não pode ser usado. Com o ajax assíncrono, usamos callbacks:

function meuAlgoritmo() { // Fazer o processamento 1. chamadaAjax(parametrosNecessarios, function(resposta) { // Fazer o processamento 2. chamadaAjax(maisParametros, function(resposta2) { // Fazer o processamento 3. chamadaAjax(parametros, function(resposta3) { // etc. }); }); }); }
O código funciona, mas a estrutura dele se torna uma verdadeira macarronada de tão confuso que fica.
Uma alternativa seria utilizar eventos:

[code]function meuAlgoritmoParte2(resposta) {
// Fazer o processamento 2.
chamadaAjax(maisParametros, meuAlgoritmoParte3);
}

function meuAlgoritmoParte3(resposta2) {
// Fazer o processamento 3.
chamadaAjax(parametros, meuAlgoritmoParte4);
}

function meuAlgoritmoParte4(resposta3) {
// etc.
}

function meuAlgoritmo() {
//Ler um monte de dados
chamadaAjax(parametrosNecessarios, meuAlgoritmoParte2);
}[/code]
Neste caso, o algoritmo foi picotado em vários pedaços espalhados. Além disso as variáveis definidas em uma parte do algoritmo não são facilmente visíveis nas outras partes, o que acaba exigindo mais gambiarras para torná-las visíveis. O código agora passa a ser um outro tipo de espaguete, em alguns casos melhor e em outros pior.

Um fato complicador é quando você quer fazer algo como o seguinte:

function foo() { var x = minhaFuncao(); // Faz qualquer coisa com x. }
Daí, quando você vai implementar minhaFuncao(), está o ajax lá no meio e você simplesmente não tem como retornar um valor.

Agora vem a pergunta:
Alguém conhece alguma abordagem ou design pattern que consiga fazer um ajax eficiente, assíncrono e ao mesmo tempo limpo e estruturado?

Oi victor,

Então, quando eu preciso de um comportamento síncrono com ajax (quando não posso usar callbacks) eu simplesmente configuro async: false no jQuery.
Até agora não tive problemas.

Dê uma olhada aqui: http://docs.jquery.com/Ajax/jQuery.ajax#options

Obrigado pela resposta, David.

É exatamente por isso que não posso e não quero usar ajax síncrono.

[quote=victorwss]Obrigado pela resposta, David.

É exatamente por isso que não posso e não quero usar ajax síncrono.[/quote]

Oi Victor.

Realmente o browser para, mas se forem operações rápidas, não sei se pode atrapalhar tanto. Vc pode mudar o estado da GUI para mostrar que o usuário deve esperar. Vc poderia talvez criar algumas flags para indicar que algo está ocorrendo e usar um setInterval para verifica-las, mas acho que fica mais complexo do que as soluções q vc postou.

[]´s

Bem, na verdade o que quero fazer é um processamento em background enquanto o usuário está trabalhando e em alguns casos, no cliente às vezes a conexão fica horrivelmente lenta (ex: Speedy, discada ou 3G da claro). Portanto travar o browser é simplesmente proibido no meu caso.

É, acho que vou ter que comer o macarrão por algum tempo… :frowning:

Tá mais parecendo uma aplicação distribuída em que o servidor é o nó mestre, e os browsers são os processadores escravos.

Gostei mais da idéia dos eventos, mas você precisa organizar(categorizar) isso melhor, separar as responsabilidades.

Se tiver como identificar as respostas do servidor por tipo, daria para fazer uma função única de recebimento e análise que chamaria em background a próxima função-processadora desses dados, como se fosse instanciar um objeto do tipo Runnable e rodá-lo.

Sobre processamento em background em javascript, só conheço os Web Workers, disponível(preview) nas versões mais novas dos bons navegadores.