动态包含的Javascript和依赖项

时间:2013-08-29 00:29:34

标签: javascript ajax asynchronous

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

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

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

  1. 语义上更正确
  2. 更容易找到用于调试的脚本(独特的文件名比匿名脚本块和调试器语句更容易查看)
  3. 跨域请求。我知道我可以尝试使用XDomainRequest,但大多数服务器都不会为此设置,我希望能够在CDN上引用外部脚本。
  4. 我尝试过的东西几乎让我得到了我需要的东西。我保留了每次使用时都列出的列表。当其中一个脚本加载时,我会使用任何引用并将它们合并到刚刚加载的文件的正确对象中,并清除全局列表。这实际上似乎在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]
    

1 个答案:

答案 0 :(得分:0)

值得称道的是,你正在接受这样一个教育项目。

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

好消息是:

  • 无需知道您所在的文件
  • 无需弄乱eval。

你实际上拥有你需要的一切: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);
}