Короткий зміст: Чи існують чітко встановлені моделі найкращої практики, які я можу дотримуватися, щоб не читати код, незважаючи на використання асинхронного коду та зворотних викликів?
Я використовую бібліотеку JavaScript, яка робить багато матеріалів асинхронно і сильно покладається на зворотні дзвінки. Здається, що написання простого методу "навантаження А, завантаження В, ..." стає досить складним і важко дотримуватися, використовуючи цю схему.
Дозвольте навести (надуманий) приклад. Скажімо, я хочу завантажити купу зображень (асинхронно) з віддаленого веб-сервера. У C # / async я б написав щось подібне:
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();
Розташування коду слідує за "потоком подій": Спочатку кнопку запуску вимкнено, потім завантажують зображення ( await
гарантує, що користувальницький інтерфейс залишається чуйним), а потім кнопку запуску знову ввімкнено.
У JavaScript, використовуючи зворотні дзвінки, я придумав таке:
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);
Я думаю, що недоліки очевидні: мені довелося переробити цикл у рекурсивний виклик; код, який повинен бути виконаний в кінці кінця, знаходиться десь посередині функції, код, що починає завантаження ( loadImage(0)
), знаходиться в самому дні, і взагалі набагато важче читати та слідкувати. Це некрасиво, і мені це не подобається.
Я впевнений, що я не вперше зіткнувся з цією проблемою, тому моє запитання таке: чи існують чітко встановлені моделі найкращої практики, які я можу дотримуватися, щоб не читати код, незважаючи на використання асинхронного коду та зворотних викликів?
LoadImageAsync
насправді заклик до Ext.Ajax.request
Sencha Touch.
async.waterfall
це ваша відповідь.