MDL-57009 js: Skip ajax request for same string

This is done by caching the first promise generated to fetch a string.
This commit is contained in:
Damyon Wiese 2017-01-03 16:19:22 +08:00
parent f99313477d
commit dcdf7c6155
2 changed files with 39 additions and 14 deletions

View File

@ -1 +1 @@
define(["jquery","core/ajax","core/localstorage"],function(a,b,c){return{get_string:function(a,b,c,d){var e=this.get_strings([{key:a,component:b,param:c,lang:d}]);return e.then(function(a){return a[0]})},get_strings:function(d){var e,f=a.Deferred(),g=[],h=0,i=!1;for(h=0;h<d.length;h++)if(e=d[h],"undefined"==typeof e.lang&&(e.lang=a("html").attr("lang").replace("-","_")),"undefined"==typeof M.str[e.component]||"undefined"==typeof M.str[e.component][e.key]){var j=c.get("core_str/"+e.key+"/"+e.component+"/"+e.lang);j?("undefined"==typeof M.str[e.component]&&(M.str[e.component]=[]),M.str[e.component][e.key]=j):i=!0}if(i){var k=[];for(h=0;h<d.length;h++)e=d[h],k.push({methodname:"core_get_string",args:{stringid:e.key,component:e.component,lang:e.lang,stringparams:[]}});var l=b.call(k,!0,!1);a.when.apply(null,l).done(function(){var a=0;for(a=0;a<arguments.length;a++)e=d[a],"undefined"==typeof M.str[e.component]&&(M.str[e.component]=[]),M.str[e.component][e.key]=arguments[a],c.set("core_str/"+e.key+"/"+e.component+"/"+e.lang,arguments[a]),g[a]=M.util.get_string(e.key,e.component,e.param).trim();f.resolve(g)}).fail(function(a){f.reject(a)})}else{for(h=0;h<d.length;h++)e=d[h],g[h]=M.util.get_string(e.key,e.component,e.param);f.resolve(g)}return f.promise()}}});
define(["jquery","core/ajax","core/localstorage"],function(a,b,c){var d=[];return{get_string:function(a,b,c,d){var e=this.get_strings([{key:a,component:b,param:c,lang:d}]);return e.then(function(a){return a[0]})},get_strings:function(e){var f,g=a.Deferred(),h=[],i=0,j=!1;for(i=0;i<e.length;i++)if(f=e[i],"undefined"==typeof f.lang&&(f.lang=a("html").attr("lang").replace("-","_")),f.cacheKey="core_str/"+f.key+"/"+f.component+"/"+f.lang,"undefined"==typeof M.str[f.component]||"undefined"==typeof M.str[f.component][f.key]){var k=c.get(f.cacheKey);k?("undefined"==typeof M.str[f.component]&&(M.str[f.component]=[]),M.str[f.component][f.key]=k):j=!0}if(j){var l=[],m=[],n=function(a){this.resolve(a)};for(i=0;i<e.length;i++)if(f=e[i],"undefined"!=typeof d[f.cacheKey])m.push(d[f.cacheKey]);else{var o=a.Deferred();l.push({methodname:"core_get_string",args:{stringid:f.key,component:f.component,lang:f.lang,stringparams:[]},done:n.bind(o)}),d[f.cacheKey]=o.promise(),m.push(d[f.cacheKey])}l.length>0&&b.call(l,!0,!1),a.when.apply(null,m).done(function(){var a=0;for(a=0;a<arguments.length;a++)f=e[a],"undefined"==typeof M.str[f.component]&&(M.str[f.component]=[]),M.str[f.component][f.key]=arguments[a],c.set("core_str/"+f.key+"/"+f.component+"/"+f.lang,arguments[a]),h[a]=M.util.get_string(f.key,f.component,f.param).trim();g.resolve(h)}).fail(function(a){g.reject(a)})}else{for(i=0;i<e.length;i++)f=e[i],h[i]=M.util.get_string(f.key,f.component,f.param);g.resolve(h)}return g.promise()}}});

View File

@ -28,6 +28,7 @@
/* eslint-disable no-restricted-properties */
define(['jquery', 'core/ajax', 'core/localstorage'], function($, ajax, storage) {
var promiseCache = [];
return /** @alias module:core/str */ {
// Public variables and functions.
@ -71,6 +72,7 @@ define(['jquery', 'core/ajax', 'core/localstorage'], function($, ajax, storage)
var i = 0;
var missing = false;
var request;
// Try from local storage. If it's there - put it in M.str and resolve it.
for (i = 0; i < requests.length; i++) {
@ -78,10 +80,11 @@ define(['jquery', 'core/ajax', 'core/localstorage'], function($, ajax, storage)
if (typeof request.lang === "undefined") {
request.lang = $('html').attr('lang').replace('-', '_');
}
request.cacheKey = 'core_str/' + request.key + '/' + request.component + '/' + request.lang;
if (typeof M.str[request.component] === "undefined" ||
typeof M.str[request.component][request.key] === "undefined") {
// Try and revive it from local storage.
var cached = storage.get('core_str/' + request.key + '/' + request.component + '/' + request.lang);
var cached = storage.get(request.cacheKey);
if (cached) {
if (typeof M.str[request.component] === "undefined") {
M.str[request.component] = [];
@ -103,25 +106,47 @@ define(['jquery', 'core/ajax', 'core/localstorage'], function($, ajax, storage)
}
deferred.resolve(results);
} else {
// Something is missing, we might as well load them all.
var ajaxrequests = [];
var fetchpromises = [];
// Done handler for ajax call. Must be bound to the current fetchpromise. We do this
// to avoid creating a function in a loop.
var doneFunc = function(str) {
this.resolve(str);
};
for (i = 0; i < requests.length; i++) {
request = requests[i];
ajaxrequests.push({
methodname: 'core_get_string',
args: {
stringid: request.key,
component: request.component,
lang: request.lang,
stringparams: []
}
});
// If we ever fetched this string with a promise, reuse it.
if (typeof promiseCache[request.cacheKey] !== 'undefined') {
fetchpromises.push(promiseCache[request.cacheKey]);
} else {
// Add this to the list we need to really fetch.
var fetchpromise = $.Deferred();
ajaxrequests.push({
methodname: 'core_get_string',
args: {
stringid: request.key,
component: request.component,
lang: request.lang,
stringparams: []
},
done: doneFunc.bind(fetchpromise)
});
promiseCache[request.cacheKey] = fetchpromise.promise();
fetchpromises.push(promiseCache[request.cacheKey]);
}
}
var deferreds = ajax.call(ajaxrequests, true, false);
$.when.apply(null, deferreds).done(
// Everything might already be queued so we need to check if we have real ajax requests to run.
if (ajaxrequests.length > 0) {
ajax.call(ajaxrequests, true, false);
}
$.when.apply(null, fetchpromises).done(
function() {
// Turn the list of arguments (unknown length) into a real array.
var i = 0;