Вот немного более надежная реализация. По сути, мы сохраняем объект ajax (т.е. объект обещания), чтобы закрыть его, чтобы последующие вызовы могли на него посмотреть. Если при следующих вызовах обнаруживается, что статус запроса находится в состоянии ожидания, он будет добавлять обратные вызовы к этому ожидающему запросу, а не генерировать новый запрос. jQuery будет запускать все обратные вызовы в той же последовательности, в которой они были добавлены. Однако есть вероятность, что один и тот же вызывающий абонент пытается создать запрос снова и снова. Чтобы защититься от этого, я добавил параметр callerId. Если тот же абонент сделал запрос еще раз, пока предыдущий запрос все еще находился на рассмотрении, мы просто игнорируем этот запрос. Для полноты я также добавил cachedValues. Так что если ajax-запрос уже сделан, мы не делаем его снова.
var ajaxRequestor = function ($) {
"use strict";
//privates
var cahedValues = {};
var currentAjaxRequest, callers;
//public interface
return {
getData: function (callerId, onGet, onFail, forceRefresh) {
if (forceRefresh || !cahedValues.myData) {
//If there is a pending request, don't start new one
if (!currentAjaxRequest || currentAjaxRequest.state() != "pending") {
currentAjaxRequest = $.getJSON("data/MyData.json");
callers = {}; //list of callers waiting for request
}
//if this caller is not in the list, add it and queue up its callbacks to existing request
if (!callers[callerId]) {
callers.callerId = callerId;
currentAjaxRequest.done(function (data, textStatus) {
cahedValues.myData = data;
onGet(data);
});
currentAjaxRequest.fail(function (jqxhr, textStatus, error) {
if (!!onFail) {
onFail(error);
}
else throw error;
});
}
}
else {
onGet(cahedValues.myData);
}
},
invalidateMyData: function () {
delete cahedValues.myData;
}
};
})($);