Executing a defer function without a Promise or any JS library

I am working on a library that will expose 3 methods. All three of these methods depend on another library (lets you call it libA

), and that library is loaded asynchronously.

I could write code to expose the methods as soon as the JS file finished loading, but then the user would have to defer execution until finished libA

.

I was hoping rather to expose a "version" of these three methods at once, while libA

continuing to load asynchronously in the background. Any calls to these three methods will be queued until libA

loaded. And after the libA

download is done, these 3 methods will be replaced with the real one, and the queue will be processed.

Let's say I have this:

var myLib = (function(){
    // expose 3 functions for the user to use
    return {
        "func1" : function(opts){},
        "func2" : function(opts){},
        "func3" : function(opts){}
    }
})();

      

This library will be downloaded by the user. At the same time will be loaded libA

. It may take longer than mine, or it may run out before the mines start.

So, if the user starts myLib.func1({})

and has libA

n't finished downloading, then he should queue up and then when libA

done he should execute. If, on the other hand, the libA

download finished, it will be executed immediately.

My initial thought is to do something like this:

var myLib = (function(){
    // queue the calls
    var queue {
        "func1" : [],
        "func2" : [],
        "func3" : []
    };

    // the "temp" functions that just add them to the queue
    var ret = {
        "func1" : function(opts){ queue.func1.push(opts); },
        "func2" : function(opts){ queue.func2.push(opts); },
        "func3" : function(opts){ queue.func3.push(opts); }
    }

    // this may happen before the user users my library or after
    // if it happens before then the functions will be replaced before the user calls them and they won't need to be queued
    // if it happens after then the functions will get replaced and the queued up ones will be executed
    waitForLibAToFinish(function(){
        ret.funct1 = function(opts){alert("this is the real func1");},
        ret.funct2 = function(opts){alert("this is the real func2");},
        ret.funct3 = function(opts){alert("this is the real func3");},

        // process the queue
        for(var i = 0; i < queue.func1.length; ++i)
        {
            ret.func1(queue.func1[i]);
        }

        // repeat for func2 and func3 queue
    });

    return ret;
})();

      

But this is just a bad way to do it. Plus I'll have to have a queue for each function and call each one. There must be a way to abstract this part, so it is more general for all the methods my library provides.

I am open to any ideas / suggestions. I just cannot (for many out of control reasons) use any third party libraries like Promise or JavaScript. And my code should work on IE8. Trust me, I hate this more than you.

===

I add some more contexts / details.

I know I am mentioning SharePoint, but this is not a special question.

I am creating a library that offers convenient methods to simplify other complex tasks in SharePoint. My whole library is SP call libraries. The corresponding SP libraries are loaded asynchronously. So one of two things must happen:

  • Or the user needs to wait for the corresponding SP libraries to finish loading before calling any of the methods in my library
  • Or my library must wait for the corresponding SP libraries to complete.

The SP function prompts you to "queue" up your function until the corresponding SP library is loaded ExecuteOrDelayUntillScriptLoaded

.

My library is currently built on the first option. I wanted to simplify the experience for the user so they don't need to check (via ExecuteOrDelayUntillScriptLoaded

). I can change it to the 2nd way, but there are reasons I don't want to.

Instead, I was hoping to do this: 1 check in my library ExecuteOrDelayUntillScriptLoaded

, which will "change" what my library does. Before the corresponding libraries are loaded, my library will just stop the calls. After the download is complete and ExecuteOrDelayUntillScriptLoaded

my code fires:

  • Execute everything in line
  • Change every function my library provides to execute directly, not queue
+3


source to share


1 answer


Do not perform the queue yourself. Leave the library loading and dependency resolution to the user. Just release the function that instantiates your library, the user can call it when library A is ready and return the module using the methods used.
There's even a standard on how to do this: Defining an asynchronous module . (You don't need require.js as a third party library, you can implement the basic stuff yourself)



If the user wants (needs) to call library methods before everything is loaded, they can always put premature calls before themselves in any way. But this is usually not necessary.

+1


source







All Articles