diff options
author | Winnie Hellmann <winnie@gitlab.com> | 2017-05-10 22:01:00 +0000 |
---|---|---|
committer | Clement Ho <clemmakesapps@gmail.com> | 2017-05-10 22:01:00 +0000 |
commit | b304d41232ce591bcea9a2b86df9b924950126ef (patch) | |
tree | e0e1e004e40e43d7d410dff7169d1ab70722f7eb /app/assets | |
parent | cb2f739d4844af094f62edb4e4dff1b3413a405b (diff) | |
download | gitlab-ce-b304d41232ce591bcea9a2b86df9b924950126ef.tar.gz |
Track pending requests in AjaxCache
Diffstat (limited to 'app/assets')
-rw-r--r-- | app/assets/javascripts/lib/utils/ajax_cache.js | 70 |
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(); |