动态包含的Javascript和依赖项

Dynamically Included Javascript and Dependencies

本文关键字:依赖 Javascript 包含 动态      更新时间:2023-09-26

因此,作为我自己的一种练习,我正在编写一个小的异步脚本加载器实用程序(想想require.js、head.js、yepnope.js),并遇到了一个小难题。首先,基本语法如下:

using("Models/SomeModel", function() {
  //callback when all dependencies loaded
});

现在,我想知道,当这个调用被调用时,我在哪个文件中。我可以用ajax调用来完成,这样我就可以在内容加载后标记一个标志,但在我评估它之前,标记所有使用的调用都是针对特定文件的,然后在评估之后立即取消设置标志(我知道eval是邪恶的,但在这种情况下,它首先是javascript,而不是json,所以它不是邪恶的)。我很确定这会得到我需要的,但我更喜欢用脚本标签来做这件事,原因有几个:

  1. 它在语义上更正确
  2. 更容易找到调试脚本(唯一文件名比匿名脚本块和调试器语句更容易查找)
  3. 跨域请求。我知道我可以尝试使用XDomainRequest,但大多数服务器都不会为此设置,我希望能够在CDN上引用外部脚本

我尝试了一些几乎能满足我需要的东西。我保留了每次调用using的列表。当其中一个脚本加载时,我使用任何一个引用,并将它们合并到刚加载的文件的正确对象中,然后清除全局列表。实际上,这在Firefox和Chrome中似乎可以正常工作,但在IE中失败了,因为加载事件似乎在奇怪的时候发生(jQuery引用吞下了对另一种类型的引用,最终将其显示为依赖项)。我以为我可以抓住"交互式"的readystate,但它似乎从未发生过。

所以现在我来问这里是否有人对此有任何想法。如果你们愿意,我可以发布代码,但它仍然很乱,可能很难阅读。

编辑:其他用途

//aliasing and multiple dependencies
using.alias("ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js", "jQuery");
using(["jQuery", "Models/SomeModel"], function() {
  //should run after both jQuery and SomeModel have been loaded and run
});
//css and conditionals (using some non-existant variables here)
using.css({ src: "IEFix", conditionally: browser === "MSIE" && version < 9 });
//should include the IEFix.css file if the browser is IE8 or below

为了在下面详细阐述我的回应,请将其视为文件A(并将以前的jquery别名视为仍然存在):

using(["jQuery", "B"], function() {
  console.log("This should be last (after both jQuery and B have loaded)");
  console.log(typeof($));
});

那么这将是B:

using("C", function() {
  console.log("This should be second");
});

最后,C:

console.log("This should be first");

输出应为:

This should be first
This should be second
This should be last (after both jQuery and B have loaded)
[Object Object]

值得称赞的是,你正在承担这样一个教育项目。

然而,你将无法完全按照你想要的方式完成它。

好消息是:

  • 无需知道您所在的文件
  • 没必要搞eval

事实上,你已经拥有了你所需要的一切:function reference.callback,如果你愿意的话。

using函数的粗略p代码是:

function using(modules, callback) {
  var loadedModules = []
  // This will be an ajax call to load things, several different ways to do it..
  loadedModules[0] = loadModule(modules[0]);
  loadedModules[1] = loadModule(modules[1]);
  // Great, now we have all the modules
  // null = value for `this`
  callback.apply(null,   loadedModules);
}