summaryrefslogtreecommitdiff
path: root/app/assets
diff options
context:
space:
mode:
authorWinnie Hellmann <winnie@gitlab.com>2017-05-10 22:01:00 +0000
committerClement Ho <clemmakesapps@gmail.com>2017-05-10 22:01:00 +0000
commitb304d41232ce591bcea9a2b86df9b924950126ef (patch)
treee0e1e004e40e43d7d410dff7169d1ab70722f7eb /app/assets
parentcb2f739d4844af094f62edb4e4dff1b3413a405b (diff)
downloadgitlab-ce-b304d41232ce591bcea9a2b86df9b924950126ef.tar.gz
Track pending requests in AjaxCache
Diffstat (limited to 'app/assets')
-rw-r--r--app/assets/javascripts/lib/utils/ajax_cache.js70
1 files changed, 46 insertions, 24 deletions
diff --git a/app/assets/javascripts/lib/utils/ajax_cache.js b/app/assets/javascripts/lib/utils/ajax_cache.js
index d99eefb5089..cf030d613df 100644
--- a/app/assets/javascripts/lib/utils/ajax_cache.js
+++ b/app/assets/javascripts/lib/utils/ajax_cache.js
@@ -1,32 +1,54 @@
-const AjaxCache = {
- internalStorage: { },
+class AjaxCache {
+ constructor() {
+ this.internalStorage = { };
+ this.pendingRequests = { };
+ }
+
get(endpoint) {
return this.internalStorage[endpoint];
- },
+ }
+
hasData(endpoint) {
return Object.prototype.hasOwnProperty.call(this.internalStorage, endpoint);
- },
- purge(endpoint) {
+ }
+
+ remove(endpoint) {
delete this.internalStorage[endpoint];
- },
+ }
+
retrieve(endpoint) {
- if (AjaxCache.hasData(endpoint)) {
- return Promise.resolve(AjaxCache.get(endpoint));
+ if (this.hasData(endpoint)) {
+ return Promise.resolve(this.get(endpoint));
}
- return new Promise((resolve, reject) => {
- $.ajax(endpoint) // eslint-disable-line promise/catch-or-return
- .then(data => resolve(data),
- (jqXHR, textStatus, errorThrown) => {
- const error = new Error(`${endpoint}: ${errorThrown}`);
- error.textStatus = textStatus;
- reject(error);
- },
- );
- })
- .then((data) => { this.internalStorage[endpoint] = data; })
- .then(() => AjaxCache.get(endpoint));
- },
-};
-
-export default AjaxCache;
+ let pendingRequest = this.pendingRequests[endpoint];
+
+ if (!pendingRequest) {
+ pendingRequest = new Promise((resolve, reject) => {
+ // jQuery 2 is not Promises/A+ compatible (missing catch)
+ $.ajax(endpoint) // eslint-disable-line promise/catch-or-return
+ .then(data => resolve(data),
+ (jqXHR, textStatus, errorThrown) => {
+ const error = new Error(`${endpoint}: ${errorThrown}`);
+ error.textStatus = textStatus;
+ reject(error);
+ },
+ );
+ })
+ .then((data) => {
+ this.internalStorage[endpoint] = data;
+ delete this.pendingRequests[endpoint];
+ })
+ .catch((error) => {
+ delete this.pendingRequests[endpoint];
+ throw error;
+ });
+
+ this.pendingRequests[endpoint] = pendingRequest;
+ }
+
+ return pendingRequest.then(() => this.get(endpoint));
+ }
+}
+
+export default new AjaxCache();