Асинхронные вызовы JavaScript, которые заполняют некоторые свойства - PullRequest
5 голосов
/ 22 ноября 2011

У меня есть объект javascript, в состав которого входит несколько строк изображения. При создании экземпляра этого объекта немедленно вызывается AJAX-вызов для заполнения этого свойства.

Мои функции просмотра одновременно пытаются прочитать только что созданные экземпляры и пытаются отобразить этот объект. Как и ожидалось, вызов AJAX может еще не завершиться, поэтому он не сможет прочитать правильный URL-адрес изображения.

Одним из решений этой проблемы является передача некоторой функции обратного вызова с помощью вызова AJAX, который изменяет источник изображения после завершения, но это создает большую зависимость от модели и вида, и я пытаюсь сохранить Мой MVC настолько отдельный, насколько это возможно, поэтому моя функция просмотра сейчас просто берет этот объект в качестве параметра, читает все свойства и показывает его.

Сделать AJAX синхронным не вариант, потому что у меня довольно много инициализируемых объектов, и одновременно будет отображаться только один, поэтому синхронизация всех вызовов AJAX будет слишком дорогой компромисс.

Какой хороший способ решить эту проблему? Функция просмотра имеет вид:

function displayObj(object) {
    var prop1 = object.getProp1();
    // this could be the image file that depends on AJAX result
    var prop2 = object.getProp2(); 
}

В идеале я хотел бы делегировать эту задачу получателю, чтобы функции представления не приходилось беспокоиться о состоянии интервала объекта. Получатель мог бы справиться с этим, проверив, есть ли еще изображение, если нет, то подождать, а затем вернуть, только если есть фактическая строка изображения. Однако ожидание блокировки наверняка заблокирует процесс AJAX, так что это тупик, а неблокирующее ожидание вернет получатель, а функция представления получит нулевые данные.

Пожалуйста, пролите некоторый свет на эту ситуацию или предложите альтернативные способы организации своего кода. Большое спасибо!

Ответы [ 2 ]

0 голосов
/ 23 ноября 2011

Поскольку из ваших комментариев вы используете jQuery, я рекомендую вам вызвать метод done() запроса, возвращенного методом ajax(). Например,

var request = $.ajax("example.php");
request.done(notifyWhenSuccess);
request.fail(notifyWhenFailed);

Этот запрос, возвращаемый jQuery, является расширенным набором шаблона Promise от CommonJS. Кроме того, только потому, что он находится в jQuery, не размещайте часть представления ajax-вызова, а рассматривайте его как часть модели. Используйте метод done() для обновления модели, а затем уведомите представление о событии изменения данных.

0 голосов
/ 22 ноября 2011

Я был бы немного менее строг с ролями MVC и позволил бы объекту модели вернуть объект DOM <img>.

// model object starts loading upon instantiation
var loader = new Loader();

// however the img tag is available immediately.
// the loader will update the src when ajax
// calls complete.
document.body.appendChild(loader.getImg());
...