Resumo: Existem alguns padrões de práticas recomendadas bem estabelecidos que posso seguir para manter meu código legível, apesar de usar código assíncrono e retornos de chamada?
Estou usando uma biblioteca JavaScript que faz várias coisas de forma assíncrona e depende muito de retornos de chamada. Parece que escrever um método simples "carregar A, carregar B, ..." se torna bastante complicado e difícil de seguir usando esse padrão.
Deixe-me dar um exemplo (artificial). Digamos que eu queira carregar um monte de imagens (de forma assíncrona) de um servidor web remoto. Em C # / assíncrono, eu escreveria algo como isto:
disableStartButton();
foreach (myData in myRepository) {
var result = await LoadImageAsync("http://my/server/GetImage?" + myData.Id);
if (result.Success) {
myData.Image = result.Data;
} else {
write("error loading Image " + myData.Id);
return;
}
}
write("success");
enableStartButton();
O layout do código segue o "fluxo de eventos": primeiro, o botão Iniciar é desativado, as imagens são carregadas ( await
garante que a interface do usuário permaneça responsiva) e, em seguida, o botão Iniciar é ativado novamente.
Em JavaScript, usando retornos de chamada, eu vim com isso:
disableStartButton();
var count = myRepository.length;
function loadImage(i) {
if (i >= count) {
write("success");
enableStartButton();
return;
}
myData = myRepository[i];
LoadImageAsync("http://my/server/GetImage?" + myData.Id,
function(success, data) {
if (success) {
myData.Image = data;
} else {
write("error loading image " + myData.Id);
return;
}
loadImage(i+1);
}
);
}
loadImage(0);
Eu acho que as desvantagens são óbvias: tive que refazer o loop em uma chamada recursiva, o código que deveria ser executado no final fica em algum lugar no meio da função, o código que inicia o download ( loadImage(0)
) está bem no fundo, e geralmente é muito mais difícil de ler e seguir. É feio e eu não gosto.
Tenho certeza de que não sou o primeiro a encontrar esse problema, então minha pergunta é: Existem alguns padrões de práticas recomendadas bem estabelecidos que posso seguir para manter meu código legível, apesar de usar código assíncrono e retornos de chamada?
LoadImageAsync
é de fato uma chamada Ext.Ajax.request
do Sencha Touch.
async.waterfall
é a sua resposta.