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: {},
        //...