【问题标题】:Dynamically Included Javascript and Dependencies动态包含的 Javascript 和依赖项
【发布时间】:2013-08-29 00:29:33
【问题描述】:

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

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

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

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

我尝试了一些几乎得到了我需要的东西。我保留了每次使用被调用的列表。当其中一个脚本加载时,我会使用任何引用并将它们合并到刚刚加载的文件的正确对象中,并清除全局列表。这实际上在 Firefox 和 Chrome 中似乎工作正常,但在 IE 中失败,因为加载事件似乎在奇怪的时间发生(jQuery 引用吞噬了对另一种类型的引用并最终将其显示为依赖项)。我以为我可以锁定“交互式”就绪状态,但它似乎永远不会发生。

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

编辑:其他用法

//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]

【问题讨论】:

  • 看看this comment
  • 那么脚本是否会在某个时刻进入交互状态并且不会为其触发 onreadystatechange 事件?
  • 回答了我自己的问题。是的,这就是它的作用,但目前仅在 IE 中。看起来我的问题的答案是对 IE 使用一种方法,对其他所有方法使用另一种方法(尽管这与课程的标准差不多)

标签: javascript ajax asynchronous


【解决方案1】:

值得称赞的是,您正在从事这样一个教育项目。

但是,您将无法按照您想要的方式完成它。

好消息是:

  • 无需知道您在哪个文件中
  • 无需乱用 eval。

实际上,你需要的一切都在那里:A function reference. A 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);
}

【讨论】:

  • 好吧,我遗漏了一些用法。假设有 3 个文件,A、B 和 C。A 包含 B 的 using 块,B 包含 C 的 using 块。我想确保这些文件的回调从 B 中的一个到 A 中的一个. using 调用也可以获取多个文件或文件的别名,因此它实际上就是获取映射的依赖关系并使用它来确定何时应该调用某些回调。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多