我可以强制jQuery的$ .each按顺序迭代文件吗?

时间:2014-02-05 14:41:18

标签: javascript jquery html mustache

我创建了一个小的脚本加载器函数,它将遍历一个填充了目录中文件名的javascript对象。这用于动态加载Mustache模板化文件以创建页面。

我创建了javascript对象,按照我希望它们输出到页面的顺序列出模板,但有时当我加载页面时元素的顺序不正确。我知道理论上$ .each()'确实'按顺序从上到下迭代,但我想知道是否有某种方式我可以明确强制它去做以避免偶尔不正确布局的页面。

var loadModules = function(){
var templates = {
    1 : 'header',
    2 : 'about' 
}
$.each(templates, function(key, value) {
    $.getScript("js/modules/"+value+".js", function(){
        Init();
    });
});
}

这是代码片段,我不时会在加载页面时看到“关注”部分显示在“标题”上方。有什么方法可以阻止这种情况发生,还是只是一个“浏览器打嗝”?

我创建了'templates'对象以指定页面元素的顺序,但它似乎只在大多数情况下工作。

3 个答案:

答案 0 :(得分:1)

更新如果您不想更改模板的结构以便它们可以异步加载,那么您可能不得不退回递归加载方法。这将类似于同步加载资源,因为您将确保一次只运行一个请求。

var templates = [
    'header',
    'about'
    /*....*/
];

//load up your templates 1 by 1 in a recursive loop
(function loadNextTemplate(index) {
    if(index >= templates.length) return; //base case
    $.getScript("js/modules/" + templates[index] + ".js")
     .then(function() {
        Init();
        loadNextTemplate(index + 1);
     });
})(0);

答案 1 :(得分:0)

然后,您致电$.getScript发送XMLHttpRequestasync默认使用$.ajax$.getScript $.ajax是javascript文件的each短调用。那么Init正在运行它发送2个异步AJAX请求,而不保证请求的结束顺序。

如果您在2个ajax请求结束后拨打jQuery Deffered/Promises的内容,请使用$.when($.getScript("js/modules/header.js"), $.getScript("js/modules/about.js")).done(function(){ Init();//Init will call after to AJAX requests ends, but without its order }); pattern

header.js

如果您需要首先加载about.js并且$.when($.getScript("js/modules/header.js").then($.getScript("js/modules/about.js")).done(function(){ Init();//header loads, after this about loads, after this Init will call }); 必须是第二个,请使用以下模式:

AMD

如果您需要加载10-15个js文件,请尝试requirejs使用requirejs。它需要一些特殊的代码包装函数,但Deffered/Promises更有用。 至于我使用{{1}}进行15次回调并不是地狱。

答案 2 :(得分:0)

解决。 我没有使用始终异步的$ .getScript,而是选择使用简单的ajax调用设置 async 调用的 false 值。由于ajax调用的 for loop async:false 值,这总是按照数组中列出的顺序加载脚本。例如:

var loadModules = function(){
//List modules in templates array in order you want them to appear in the DOM
var templates = [
    'header',
    'about' 
];


var i;
for (i=0; i<templates.length; ++i){
    $.ajax({
        url: "js/modules/"+templates[i]+".js",
        dataType: 'script',
        success: function(){
            Init();
        },
        async: false
    });
}

请你帮忙解决这个问题。我从每个答案/建议中略过一点并将它们全部应用,所以我不知道是谁给出了正确答案的答案。