Looking at the docs for systemjs I can not find an example of loading multiple dependencies at the same time. I would expect an api something like...
System.import(['jquery.js','underscore.js']).then(function($, _) {
// ready to go with both jQuery and Underscore...
});
I would expect it to use promises to load all dependencies in parallel, and execute the callback once all are complete. Is this possible? If not, is there a reason why this functionality is not implemented?
Possibly the shortest and DRYest way would be applying a [].map()
to the System.import
and then destructure its results:
Promise.all([
'jquery',
'underscore'
].map(url => System.import(url))).then(function ([$, _]) {
// do stuff with results
});
Keep in mind that Destructuring still needs to be transpiled at the moment of writing this.
If you don't want to transpile you could write your own wrapper and spread script:
function spread(callback) {
return function (args) {
return callback.apply(undefined, args);
}
}
function import(deps) {
return Promise.all(deps.map(function (url) {return System.import(url);}));
}
and load it like:
import(['jquery', 'underscore']).then(spread(function ($, _) { /*...*/ }));
This is possible with Promise.all:
Promise.all([
System.import('jquery'),
System.import('underscore')
]).then(function(modules) {
var jquery = modules[0];
var underscore = modules[1];
});
But it is ugly as you can see. There is talk of considering allowing an array like your example at the spec level, but it would need to be in the module spec since this is a spec loader.
The better alternative really is to only have one entry point for an application, app.js
and then have that load dependencies.
This is how i would do it, take it carrefully: it's not tested.
var SystemImport = System.import;
System.import = function (name, options) {
if (Object.prototype.toString.call(name) !== '[object Array]')
return SystemImport.apply(this, arguments);
var self = this,
imports = Promise.all(name.map(function (name) {
return SystemImport.call(self, name); // should i pass options ?
}));
return {
then: function (onfulfill, onreject) {
return imports.then(function (dependencies) {
return onfulfill.apply(null, dependencies);
}, onreject);
}
};
};
This snippet will replace System.import
with a wrapped version of itself allowing to use array of dependencies.
It returns a "thennable" object, this should work fine with any compliant promise implementation.
As the .spread
method is not in the Promise A+ spec, this is the most spec compliant way I can think of...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With