查看systemjs的文档,我找不到同时加载多个依赖项的示例。我希望有一个类似于...的api
System.import(['jquery.js','underscore.js']).then(function($, _) {
// ready to go with both jQuery and Underscore...
});
我希望它使用 Promise 并行加载所有依赖项,并在所有依赖项完成后执行回调。这可能吗?如果没有,是否有没有实现此功能的原因?
查看systemjs的文档,我找不到同时加载多个依赖项的示例。我希望有一个类似于...的api
System.import(['jquery.js','underscore.js']).then(function($, _) {
// ready to go with both jQuery and Underscore...
});
我希望它使用 Promise 并行加载所有依赖项,并在所有依赖项完成后执行回调。这可能吗?如果没有,是否有没有实现此功能的原因?
这可以通过 Promise.all 实现:
Promise.all([
System.import('jquery'),
System.import('underscore')
]).then(function(modules) {
var jquery = modules[0];
var underscore = modules[1];
});
但正如你所见,它很丑陋。有人谈论考虑在规范级别允许像您的示例这样的数组,但它需要在模块规范中,因为这是一个规范加载器。
更好的选择实际上是只有一个应用程序的入口点,app.js
然后具有该负载依赖关系。
我就是这样做的,小心翼翼:它没有经过测试。
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);
}
};
};
该片段将替换System.import
为自身的包装版本,允许使用依赖数组。
它返回一个“thennable”对象,这应该适用于任何兼容的 Promise 实现。
由于该.spread
方法不在 Promise A+ 规范中,这是我能想到的最符合规范的方式...
可能最短和最干燥的方法是将 a[].map()
应用于System.import
然后解构其结果:
Promise.all([
'jquery',
'underscore'
].map(url => System.import(url))).then(function ([$, _]) {
// do stuff with results
});
请记住,在撰写本文时仍需要对Destructuring进行转译。
如果您不想转译,您可以编写自己的包装器和传播脚本:
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);}));
}
并像这样加载它:
import(['jquery', 'underscore']).then(spread(function ($, _) { /*...*/ }));
我一直在寻找同样的东西。我目前正在使用 Bluebird、Promise.all 和 Promise.spread 来执行此操作。这就像我能写的一样“好”。
Promise.all([
SystemJS.import('jquery'),
SystemJS.import('axios')
]).spread(function(jquery, axios){
return jquery < axios;
});