1

我现在有大约六个 JS 类文件。我没有放入一堆标签,而是使用 jQuery 动态加载它们——按顺序——像这样:

var classes = ["A","B","C"...];
blah.load = function(callback) {
    for (var i in classes) {
        console.log("Loading "+blah.RootURL+"/"+classes[i]+".js");
        $.ajax({
            async: true,
            url: blah.RootURL+"/"+classes[i]+".js",
            dataType: "script",
            error: function(jqxhr, status, error) {
                console.log("Unable to load "+classes[i]+": "+status+", "+error);
            },
            success: function(data, status, xhr) {
                if (window.tmpLoadCount) {
                    window.tmpLoadCount++;
                } else {
                    window.tmpLoadCount = 1;
                }

                if (window.tmpLoadCount == classes.length) {
                    console.log("Initializing...");
                    callback();
                }
            }
        });
    }
};

目前我正在使用多个脚本标签,所以我可以继续工作。我在使用 jQuery 方法时遇到的问题是,有时在 [重新] 加载时,以前的脚本似乎在下一个脚本加载之前没有执行(或完成执行),即使使用async: true. 我的课很短很简单。我会通过“加载”日志看到脚本加载,但后来看到一个错误,如“无法加载 B:A 不是构造函数”(如果 B 继承自 A),这表明 A 不完全B.prototype=new A();行执行时加载。

我在网上找到了一个对此的引用,并建议添加一个setTimeout()调用以给引擎一些时间,并建议这仅在处理 jQuery 的“成功”回调中的内容时发生......不幸的是我不确定如何确保一切在不使用成功回调的情况下以动态方式按顺序加载。

除了许多<script/>标签或缩小(这使调试更加困难)或需要更改类之外,是否有人对如何彻底避免这种“竞争条件”提出建议?我目前不太喜欢的想法是让每个类文件中的最后一行将其类名添加到全局静态属性中,并让 ajax 调用使用间隔来检查该属性以确定它是否应该加载下一个文件...bleh。

4

2 回答 2

3

RequireJS实际上就是为这种情况而设计的。你应该认真考虑使用它。我个人认为Aaron Hardy 的这篇博文比他们自己的文档中实际包含的内容更好、更短、更清晰地描述了 RequireJS 是什么以及如何使用它。您可能需要几分钟的时间来阅读它,我认为您会发现它是一个非常好的解决方案。

于 2012-04-16T15:16:31.007 回答
0

您在当前场景中可以做的一件事是仅在当前完成时才调用下一个脚本的加载。即在success函数中是这样的。

function something(i){
    $.ajax({
                async: true,
                url: blah.RootURL+"/"+classes[i]+".js",
                dataType: "script",
                error: function(jqxhr, status, error) {
                    console.log("Unable to load "+classes[i]+": "+status+", "+error);
                },
                success: function(data, status, xhr) {
                    if (window.tmpLoadCount) {
                        window.tmpLoadCount++;
                    } else {
                        window.tmpLoadCount = 1;
                    }
    something(window.tmpLoadCount);
                    if (window.tmpLoadCount == classes.length) {
                        console.log("Initializing...");
                        callback();
                    }
                }
            });
}
于 2012-04-16T15:11:10.240 回答