Riepilogo: ci sono alcuni modelli di best practice consolidati che posso seguire per mantenere il mio codice leggibile nonostante l'uso di codice asincrono e callback?
Sto usando una libreria JavaScript che fa molte cose in modo asincrono e fa molto affidamento sui callback. Sembra che scrivere un semplice metodo "carica A, carica B, ..." diventa piuttosto complicato e difficile da seguire usando questo modello.
Lasciatemi fare un esempio (inventato). Diciamo che voglio caricare un sacco di immagini (in modo asincrono) da un server web remoto. In C # / async, scriverei qualcosa del genere:
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();
Il layout del codice segue il "flusso di eventi": in primo luogo, il pulsante di avvio è disabilitato, quindi le immagini vengono caricate ( await
assicura che l'interfaccia utente rimanga reattiva) e quindi il pulsante di avvio viene nuovamente abilitato.
In JavaScript, usando i callback, ho pensato a questo:
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);
Penso che gli svantaggi siano ovvi: ho dovuto rielaborare il ciclo in una chiamata ricorsiva, il codice che dovrebbe essere eseguito alla fine è da qualche parte nel mezzo della funzione, il codice che inizia il download ( loadImage(0)
) è in fondo, ed è generalmente molto più difficile da leggere e seguire. È brutto e non mi piace.
Sono sicuro di non essere il primo a riscontrare questo problema, quindi la mia domanda è: ci sono alcuni schemi di best practice ben consolidati che posso seguire per mantenere il mio codice leggibile nonostante l'uso di codice asincrono e callback?
LoadImageAsync
in realtà è una chiamata a Ext.Ajax.request
di Sencha Touch.
async.waterfall
è la tua risposta.