I am working on a library that will expose 3 methods. All three of these methods depend on another library (lets call it libA
) having been loaded and that library loads asynchronously.
I could write the code to expose the methods as soon as the JS file has finished loading but then the user would have to defer execution until libA
has finished.
I was hoping to, rather, expose "a version" of those 3 methods immediately while libA
continues to load asynchronously in the background. Any calls to those 3 methods would get queued up until libA
is done loading. And after libA
is done loading those 3 methods would get replaced with the real one and the queue would 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 loaded by the user. At the same time libA
will also be loaded. It may take longer to load then mine or it may finish before mine starts.
So if the user runs myLib.func1({})
and libA
has not finished loading then it should get queued up and then when libA
is done it should execute. If, on the other hand, libA
has finished loading then it would execute 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 just seems like 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 that part out so its more generic for all the methods my library exposes.
I'm open to any ideas/suggestions. I just cannot (for numerous reasons out of my control) use any 3rd party libraries like Promise or JavaScript. And, my code has to work on IE8. Trust me, I hate it more than you do.
===
I'm adding some more context/details.
I know I mention SharePoint but this is not an SP specific question.
I am building a library that offers convenience methods to simplify otherwise complicated tasks in SharePoint. All my library does is call SP libraries. The relevant SP libraries are loaded asynchronously. So one of two things needs to happen:
The function SP offers to let you "queue" up your function until a relevant SP library is loaded is ExecuteOrDelayUntillScriptLoaded
.
My library is currently built on the first option. I wanted to simplify the experience for the user so they don't have to check (by way of ExecuteOrDelayUntillScriptLoaded
). I could change it to the 2nd way but there are reasons I don't want to.
Instead, what I was hoping to do is include 1 check in my library with ExecuteOrDelayUntillScriptLoaded
that would "modify" what my library does. Before the relevant libraries are done loading my library would just queue up the calls. And after it is done loading and ExecuteOrDelayUntillScriptLoaded
fires, my code would:
Don't do the queuing yourself. Leave the library loading and dependency resolution to the user. Just expose a function that instantiates your library, the user may call it when library A is ready and get the module with usable methods back.
There even already is a standard on how to do that: Asynchronous Module Definition. (You don't need require.js as a third-party library, you can implement the bare essentials yourself)
If the user wants (needs) to call your library methods before everything is loaded, they can always queue the premature invocations themselves in any manner they want. But usually this should not be necessary.