Skip to content

Instantly share code, notes, and snippets.

@punmechanic
Last active August 29, 2015 14:19
Show Gist options
  • Save punmechanic/5aad23aa6de167fb6be7 to your computer and use it in GitHub Desktop.
Save punmechanic/5aad23aa6de167fb6be7 to your computer and use it in GitHub Desktop.
yet another javascript dependency injector
;(function(window, Promise, exports) {
'use strict';
var types = {};
/**
* Register a type with the injector.
* @param {String} name The name of the type to register.
* @param {Function} constructor The constructor for the injector. Constructors can be regular function; `this` will be bound to the constructor function itself. Constructs may register their dependencies by placing an $inject field that is a string array. Each dependency will be resolved before instantiating the constructor. If the dependency cannot be fulfilled, an Error will be thrown.
*/
exports.register = function(name, constructor) {
var bundle = {
dependencies: constructor.$inject || [],
constructor: constructor
};
types[name] = bundle;
};
var resolveQueue = [];
/**
* Resolve a type. Note that this function will do nothing until the DOM has been loaded (this allows for the injector to be sure it has found every dependency).
* @param {String} name The name of the type to resolve.
* @return {Promise<Object>} A promise that will resolve to the resolved object, or reject upon error.
*/
exports.resolve = function(name) {
return new Promise(function(resolve, reject) {
resolveQueue.push(function() {
var bundle = types[name];
if(bundle === undefined) {
reject(new Error('could not find type: '+ name));
return;
}
var dependencies = [];
for (var i = 0; i < bundle.dependencies.length; i++) {
var dependency = exports.resolve(bundle.dependencies[i]);
dependencies.push(dependency);
};
return Promise.all(dependencies)
.then(function(resolvedDependencies) {
resolve(bundle.constructor.apply(bundle.constructor, resolvedDependencies));
});
});
});
};
// Only process the resolve queue after we have loaded.
// This is because we may not have the guarantee that all of our scripts
// (and thus types) have been loaded yet, so some scripts loaded in the incorrect
// order may depend on other scripts that are not loaded yet.
window.addEventListener('load', function() {
for (var i = 0; i < resolveQueue.length; i++) {
resolveQueue[i]();
};
});
})(window, Promise, window.inject = window.inject || {});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment