JSFiddle - React, Tailwind, and code Playground
HTML
<p class='a'></p>
<p class='b'></p>
<p class='a'></p>
<p class='a'></p>
<p class='b'></p>
<p class='a'></p>
<p class='b'></p>
JavaScript
(function () {
// _cache is static for all widgets
// structure is {key1:{data:{},status:"",callbacks:[f1,f2,...]}, key2:{...}}
var _cache = {};
// Do a server request. Run callbacks for this key on finish.
function _serverRequest(key, query) {
console.log("Server Request"); // So we can count how many were performed
_cache[key].status = "inprogress"
var fakeresults = "result of " + query + " with key: " + key;
// $.json(...) // Do your actual query here
// .done( function(){} )
setTimeout(function () { //simulate a server request
_cache[key].data = fakeresults;
_cache[key].status = "done";
$.each(_cache[key].callbacks, function () { // run all callbacks in queue
this(_cache[key].data);
});
_cache[key].callbacks = []; // empty the queue
});
};
// Do a server request unless one is already being performed
// by a widget with the same key. If it is, wait for it to finish
// and use it's result.
function _serverRequestOrFromCache(key, query, callback) {
if (_cache[key] == null) { // if this key is not cached
_cache[key] = {
status: "",
callbacks: [callback],
data: {}
}
_serverRequest(key, query);
} else if (_cache[key].status === "inprogress") { // if another widget is getting data
_cache[key].callbacks.push(callback);
} else if (_cache[key].status === "done") {
// This could be changed to use the cache if the query is the same.
// Currently it only uses the cache if a query is in progress.
_cache[key].callbacks.push(callback);
_serverRequest(key, query);
}
};
$.widget("me.mywidget", { // Create the widget
options: {
key: "default"
},
mydata: {},
//...