Показать сообщение отдельно
Старый 01.07.2013, 18:13
maxkar вне форума Посмотреть профиль Отправить личное сообщение для maxkar Найти все сообщения от maxkar
  № 7  
Ответить с цитированием
maxkar

Регистрация: Nov 2010
Сообщений: 497
Цитата:
Сообщение от KumoKairo Посмотреть сообщение
Добрый день, вопрос в следующем:
У меня пока два решения. И оба, прямо сказать, не очень меня вдохновляют:
Я применяю третье решение. Подписываться "в каждом месте" на обработчики событий мне не интересно. Причем в обоих ваших решениях все равно нужно подписаться два раза. Поэтому пришлось ввести понятие асинхронной операции. AsyncOperation. Она может быть в одном из трех состояний: операция (и степень ее завершенности), ошибка (с описанием) или результат (со значением результата). Плюс возможность подписки на смену состояний (смена "степени завершенности" тоже диспатчится). Все "исходно асинхронные" операции вроде загрузки по сети обучены возвращать этот асинхронный статус. Ну и для красоты сделано несколько комбинаторов.

Async.applySync(function, array). Применяет синхронную функцию (т.е. возвращающую сразу "результат") к аргументам. Если что-то завершилось с ошибкой, считает, что вся операция завершилась с ошибкой (и вовзращает исходный код). Возвращает AsyncOperation.
Async.applyAsync(function, arrray). Применяет асинхронную функцию к асинхронным аргументам. Например, мы загрузили данные и потом по ним будем грузить картинки. Возвращает AsyncOperation.
Async.onComplete(AsyncOperation, function). Применяет функцию, когда асинхронная операция завершилась (с любым результатам). Ничего не возвращает.
Async.onSuccess(AsyncOperation, function), Async.onFailure(AsyncOperation, function) - применяет функцию к результатам в случае успеха/ошибки.

Небольшой бонус (совершенно на другом уровне). App.monitorOp(AsyncOperation). Умеет корреткно отображать "глобальное ожидание" приложения и выводить ошибки (считает ошибки фатальными).

Итого, типичный код выглядит примерно так:
Код AS3:
function doSomething() : AsyncOperation {
  const op1 : AysncOperation = Net.loadXML("www.xml.info", parseSomeXml);
  const op2 : AsyncOperation = Net.loadImage("www.images.org/image.png");
  const xmlImages = Async.applyAsync(loadImages, [op1]);
  return Async.applySync(showWindow, [op2, xmlImages, "op-something");
}
 
function showWindow(image1 : BitmapData, otherImages : Array, notAnAsyncArgument : String) : void {
 // create and show UI window.
}
 
function loadImages(xml : SomeParsedXML) : AsyncOperation {
  return Async.gatherSuccess(Funcs.map(xml.images, function(img : SomeParsedImage):AsyncOperation {
    return Net.loadImage(img.url);
  }));
}
 
// somewhere in other code:
function onMagicButtonClick() : void {
  App.monitorOp(doSomething);
}
Под капотом оно (реализация), конечно же, считает количество загрузок и обрабатывает статусы. Но это ровно в одном месте. А вот используется асинхронность во многих местах. А еще все асинхронные комбинаторы можно в Function.prototype записать (на js я так делал, на AS не пробовал). И будет работать запись somefunction.applyAsync([arguments]).