Last active
August 29, 2015 14:19
-
-
Save punmechanic/5aad23aa6de167fb6be7 to your computer and use it in GitHub Desktop.
yet another javascript dependency injector
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;(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