0

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

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

现在,我想知道,当进行此调用时,我在哪个文件中。我可以使用 ajax 调用来完成,这样我就可以在内容加载后标记一个标志,但在我评估它之前标记所有using 调用将针对特定文件,然后在 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]
4

1 回答 1

0

Commendable that you are taking on such an educational project.

However, you won't be able to pull it off quite the way you want to do it.

The good news is:

  • No need to know what file you are in
  • No need to mess with eval.

You actually have everything you need right there: A function reference. A callback, if you will.

A rough P-code for your using function would be:

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);
}
于 2013-08-29T00:39:14.017 回答