我正在试图找出一种方法来构建一个能够注入插件的新工作框架。其思想是让每个文件异步加载。
下面是我希望如何配置我的插件:
<script id="target_root" src="assets/js/target/target.js" async="true"></script>
<script>
var target = target || {};
target.cmd = target.cmd || [];
target.cmd.push(function () {
target.loadPlugins([
{"name": "root", "src": "assets/js/target/target.root.js"},
{"name": "krux", "src": "assets/js/target/target.krux.js"}
]).then(
target.init([
{
'plugin': 'root',
'opts': {
'foo': 'bar'
}
},
{
'plugin': 'krux',
'opts': {
'foo': 'bar'
}
}
])
)
});
</script>因为我要使用内联函数(在DOM中),所以我想使用一个命令队列,它在加载时将调用所有推送函数(有点像DFP的googletag cmd )。
如前所述,每个插件都是异步加载的,因此每个插件的初始化应该只在所有插件都加载后才开始(因此使用then()函数)。
下面是我的脚本:
var target = (function(root, w, d, c) {
var queueIndex = 0,
amountPluginsLoaded = 0,
pluginsLoaded = [];
root.cmd = {
'queue': root && root.cmd ? root.cmd : [],
'push': function(fn) {
this.queue.push(fn);
this.next();
},
'next': function() {
if (this.queue.length > 0) {
this.queue.shift()();
}
}
};
root.init = function(plugins) {
};
root.loadPlugins = function(plugins) {
var i = 0,
len = plugins.length;
for(; i < len; i++) {
_loadExternalJS(plugins[i]);
}
};
function _loadExternalJS(plugin) {
var scriptRoot = d.getElementById('target_root'),
scriptElement = d.createElement('script');
scriptElement.setAttribute('type', 'text/javascript');
scriptElement.setAttribute('async', 'true');
scriptElement.onload = function() {
amountPluginsLoaded++;
pluginsLoaded.push(plugin.name);
};
scriptElement.setAttribute('src', plugin.src);
scriptRoot.parentNode.insertBefore(scriptElement, scriptRoot.nextSibling);
}
function _initPlugin(plugin) {
}
for (; queueIndex < root.cmd.queue.length; queueIndex++) {
root.cmd.next();
}
}(target || {}, window, document, console));在这里,您有基本的cmd功能,它将被覆盖,并加载每个脚本。
我似乎不能理解的是如何启动then()。我想您应该在它的onload事件的_loadExternalJS()中跟踪它(正如您在代码中看到的那样)。但是简单地添加一个if(amountPluginsLoaded === pluginsLoaded.length) { fire all inits }似乎没有效率,而且不属于该函数。这就是为什么我喜欢实现一些then()特性的原因。
有什么想法/意见吗?
发布于 2017-07-03 22:14:46
由于我没有收到有效的答案,我接受了我的无效想法:(
function _loadExternalJS(elem) {
var scriptRoot = d.getElementById('target_root'),
scriptElement = d.createElement('script'),
isElemPlugin = elem.isPlugin || typeof elem.isPlugin === "undefined",
loadAsync = elem.async || typeof elem.async === "undefined";
scriptElement.setAttribute('type', 'text/javascript');
scriptElement.setAttribute('async', loadAsync);
if (isElemPlugin) {
scriptElement.onload = function() {
jsLoaded++;
};
}
scriptElement.setAttribute('src', elem.src);
scriptRoot.parentNode.insertBefore(scriptElement, scriptRoot.nextSibling);
}对于那些想知道"then“功能的人,我做了以下工作:
target.init = function (plugins) {
//do something
return {
'then': _then
}
};
function _then(fn) {
var loaded;
loaded = w.setInterval(function () {
if (jsLoaded === pluginList.length) {
w.clearInterval(loaded);
fn();
}
}, 10);
}如果你有更好的想法,请发帖子!:)
发布于 2017-06-27 01:43:02
您可以使用promise和promise.all来检查它们是否都已加载。
root.loadPlugins = function(plugins) {
var promiseArray = plugins.map(function(plugin){
return _loadExternalJS(plugin);
});
return Promise.all(promiseArray);
};
function _loadExternalJS(plugin) {
return new Promise((resolve, reject) => {
var scriptRoot = d.getElementById('target_root'),
scriptElement = d.createElement('script');
scriptElement.setAttribute('type', 'text/javascript');
scriptElement.setAttribute('async', 'true');
scriptElement.onload = function() {
amountPluginsLoaded++;
pluginsLoaded.push(plugin.name);
resolve(plugin.name);
};
scriptElement.setAttribute('src', plugin.src);
scriptRoot.parentNode.insertBefore(scriptElement, scriptRoot.nextSibling);
});
}然后
root.loadPlugins().then(function(){
//initialize plugins
});https://stackoverflow.com/questions/44724164
复制相似问题