MAP ARG阵列以后要执行的承诺数组
我正在构建脚本的层次结构,其中所有级别的脚本都可以并行运行,但是每个级别都需要在下一个级别运行之前完成。
当我有一个固定的已知级别数量的级别时,我通过查询文档的脚本,在级别1中有一个工作,具有在ARG传递加载时返回承诺的函数,将该函数推到数组中,重复每个级别的函数,然后创建一个承诺。所有的链条用于生成的阵列:
function loadScript (script) {
return new Promise(function(resolve, reject) {
script.setAttribute("src", script.getAttribute("data-src"));
script.onload = function() {
resolve(script.src);
};
script.onerror = function() {
reject(script.src);
}
});
}
function loadScripts() {
const firstScripts = document.querySelectorAll( "script[data-type='lazy']"
+ "[data-order='1']" );
const secondScripts = document.querySelectorAll( "script[data-type='lazy']"
+ "[data-order='2']" );
let first = [];
let second = [];
firstScripts.forEach(function(element) {
first.push(loadScript(element));
});
secondScripts.forEach(function(element) {
second.push(loadScript(element));
});
Promise.all(first)
.then(Promise.all(second))
.then(function() {
console.log('all scripts loaded');
})
.catch(function(script) {
console.log(script + ' failed to load.');
});
}
我现在正在尝试将其抽象一点,因此它将与任意,未知的深度一起使用。这似乎是一个使用array.map
的好地方;但是,问题是,它实际上是在执行承诺。
因此,我正在寻找的是将调用映射到loadscript
的方法,以便以后可以打电话:
function loadScripts() {
let maxDepth = 0;
let hierarchy = [];
while ( Boolean(document.querySelector( "script[data-type='lazy']"
+ "[data-order='" + maxDepth + "']" )) ) {
hierarchy[ maxDepth ] = [ ...document.querySelectorAll(
"script[data-type='lazy'][data-order='" + maxDepth + "']" ) ];
maxDepth++;
}
hierarchy.forEach((scripts, level) => {
// these loadScript calls should ... not be calls. They should be queued to
// run later when walkHierarchy is called
hierarchy[ level ] = scripts.map((element) => loadScript( element ) );
});
walkHierarchy = async function (arr) {
for (const level of arr) await Promise.all(level);
}
walkHierarchy( hierarchy )
.then(function() {
console.log('all scripts loaded');
})
.catch(function(script) {
console.log(script + ' failed to load.');
});
}
另外,如果有一种方法可以采用WalkhierArchy
逻辑并将其包含在eReach.foreach
中,以便每个级别在进入下一个级别之前都可以完成。
I'm building up a hierarchy of scripts, where all the scripts at the same level can be run in parallel, but each level needs to complete before the next level runs.
I had this working when I had a fixed, known number of levels, by querying the document for the scripts at level 1, having a function that returns a promise when the arg passed loads, pushing that function onto an array, repeating for each level, and then creating a Promise.all chain for the resulting arrays:
function loadScript (script) {
return new Promise(function(resolve, reject) {
script.setAttribute("src", script.getAttribute("data-src"));
script.onload = function() {
resolve(script.src);
};
script.onerror = function() {
reject(script.src);
}
});
}
function loadScripts() {
const firstScripts = document.querySelectorAll( "script[data-type='lazy']"
+ "[data-order='1']" );
const secondScripts = document.querySelectorAll( "script[data-type='lazy']"
+ "[data-order='2']" );
let first = [];
let second = [];
firstScripts.forEach(function(element) {
first.push(loadScript(element));
});
secondScripts.forEach(function(element) {
second.push(loadScript(element));
});
Promise.all(first)
.then(Promise.all(second))
.then(function() {
console.log('all scripts loaded');
})
.catch(function(script) {
console.log(script + ' failed to load.');
});
}
I'm now trying to abstract it a bit, so it will work with an arbitrary, unknown depth. This seems like a fine place to use Array.map
; however, the problem is, it's actually executing the Promise.
So, what I'm looking for is a way to map the calls to loadScript
such that they can be called later:
function loadScripts() {
let maxDepth = 0;
let hierarchy = [];
while ( Boolean(document.querySelector( "script[data-type='lazy']"
+ "[data-order='" + maxDepth + "']" )) ) {
hierarchy[ maxDepth ] = [ ...document.querySelectorAll(
"script[data-type='lazy'][data-order='" + maxDepth + "']" ) ];
maxDepth++;
}
hierarchy.forEach((scripts, level) => {
// these loadScript calls should ... not be calls. They should be queued to
// run later when walkHierarchy is called
hierarchy[ level ] = scripts.map((element) => loadScript( element ) );
});
walkHierarchy = async function (arr) {
for (const level of arr) await Promise.all(level);
}
walkHierarchy( hierarchy )
.then(function() {
console.log('all scripts loaded');
})
.catch(function(script) {
console.log(script + ' failed to load.');
});
}
Alternatively, if there's a way to take the walkHierarchy
logic and include it in the hierarchy.forEach
, such that each level completed before moving on to the next, that would be fine, too.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
动态导入
也许您正在寻找 dynamigic import 它已经支持按需加载。
diy级别订单脚本加载程序
也许您不想使用
import
,或者在环境中不支持它。让我们以一个具体的例子,以便我们可以验证行为。我们从一堆无序的< scripts>
-Graph
第一步是制作
graph
of(订购,脚本,脚本)阵列)地图
-loadscripts
该图出现无关紧要。
loadscripts
将递归遍历图形,递增order
一对一。当图中找不到特定顺序时,我们知道是时候停止加载并退出 -loadscript
我们可以在此处通过修改
loadscript
to解决此处进行演示。
脚本是否成功加载。我们还添加了一个console.log
,因此我们可以看到哪个顺序loadScript
现在in -现在一起
demo
在您自己的浏览器中验证结果 -
dynamic import
Maybe you are looking for dynamic import which already supports on-demand loading.
DIY level-order script loader
Maybe you don't want to use
import
or it's not supported in your environment. Let's take a concrete example so we can verify the behaviour. We start with a bunch of unordered<scripts>
-graph
The first step is to make a
graph
of(order, script array) map
-loadScripts
It doesn't matter that the graph appears unordered.
loadScripts
will recursively traverse the graph, incrementingorder
one-by-one. When a particular order is not found in the graph, we know it is time to stop loading and exit -loadScript
We can demo this here by modifying
loadScript
toresolve
whether the script loads successfully or not. We also added aconsole.log
so we can see which orderloadScript
is called in -all together now
demo
Verify the results in your own browser -