javascript - 延迟脚本的加载直到承诺完成
问题描述
有没有办法延迟脚本标签的 onload 事件,直到脚本中的一些 Promise 完成?
一点背景:我加载了一个具有以下功能的脚本。在脚本内部调用了一些异步函数,该函数返回一个值。
const loadScript = (src, resolveWithGlobal) =>
new Promise((resolve) => {
const script = window.document.createElement("script");
script.src = src;
script.async = true;
script.onload = () => {
resolve(window[resolveWithGlobal]);
};
window.document.body.appendChild(script);
});
const lib = await loadScript("path/to/library1.js", "library2");
加载的脚本看起来类似于这个(它的行为就像加载其他脚本/库的代理)
// library1.js
(async () => {
await loadScript("path/to/library2.js", "library2");
})();
目前我只是返回要查找并loadScript
在同一个文件中进行两次调用,如果我以后想删除间接,这有点难看
const lib1 = loadScript("lib1.js", "lib1");
const lib = loadScript(lib.path, "lib2");
解决方案
对于一般情况,您可以将解析器函数放在窗口上,其名称不会与任何其他名称发生冲突——也许将随机字符串放入脚本标签的数据集中。然后让脚本在运行时检查其脚本标签中的唯一名称,并在其异步操作完成时调用解析器。
const loadScript = (src, resolveWithGlobal) =>
new Promise((resolve) => {
const script = window.document.createElement("script");
script.src = src;
script.async = true;
const uniqueId = Math.random().toString(36).substring(7);
script.dataset.uniqueId = uniqueId;
window[uniqueId] = () => {
delete window[uniqueId]
return () => {
resolve(window[resolveWithGlobal]);
};
};
script.onload = () => {
// If resolver hasn't been retrieved by the library, do it now:
window[uniqueId]?.()();
};
window.document.body.appendChild(script);
});
const lib1 = loadScript("lib1.js", "lib1");
// lib1.js
const resolve = window[document.currentScript.uniqueid]();
loadScript("path/to/library2.js", "library2")
.then(resolve);
如果脚本不执行任何异步操作,则它不需要对窗口上的解析器执行任何特殊操作 -loadScript
在这种情况下,当脚本加载时会调用它。
推荐阅读
- bluetooth - 如何在不拔下 USB/重新启动的情况下在 Linux 上重置蓝牙适配器?
- python - 在 Dropbox Python API v2 中下载文件时遇到问题
- excel - 删除“联合”非连续范围
- api - 将 Canvas LMS API 调用中的 \N 替换为 NULL
- sql - SQL:连接两个时间序列数据并计算给定时间点的总数和比率
- c++ - 多级继承中的 CRTP derived() 方法
- javascript - 在节点js中将html表数据插入mysql数据库
- html - 仅 CSS 手风琴布局
- javascript - Javascript 为什么标头脚本中的对象属性可以,但在 html 中未定义?
- react-native - 如何在 Connect 组件下的 graphql 查询中使用 $filter 变量?