Javascript $.getJSON竞态条件中的每一个?

Javascript $.getJSON竞态条件中的每一个?,javascript,jquery,ajax,Javascript,Jquery,Ajax,在jquery.getJSON中使用jquery.each()函数时出现问题。 在本例中,我在代码中处理两种类型的元素。“源”和“流” 我想使用getJSON首先获取源代码,对它们进行迭代并从中生成一个accordion头文件。然后,对于每一个“源”,我再次使用getJSON和该源的id来获取其对应的“流”。然后我将这些流附加到它的源accordion主体中,以获得所有流的列表,按它们的源排序 但是,当我获取JSON时,我的过程中的下一个语句似乎已经执行了。由于我基本上是动态构建一个大型HTML

jquery.getJSON
中使用
jquery.each()
函数时出现问题。 在本例中,我在代码中处理两种类型的元素。“源”和“流” 我想使用
getJSON
首先获取源代码,对它们进行迭代并从中生成一个accordion头文件。然后,对于每一个“源”,我再次使用
getJSON
和该源的id来获取其对应的“流”。然后我将这些流附加到它的源accordion主体中,以获得所有流的列表,按它们的源排序

但是,当我获取JSON时,我的过程中的下一个语句似乎已经执行了。由于我基本上是动态构建一个大型HTML字符串,并使用jQuery将其添加到元素中,因此该字符串无法获得它所需的所有数据

代码如下所示:

var html1 = "<div class='panel-group' id='manageAccordion'>";
$.getJSON(url, function(data){
    $.each(data, function(i, json){
        html1 += getAccordionPart(...); //creates the accordion for the given source
    });

}).done(function(){
    html1 += "</div>";
    $('#elementList').html(html);
});

function getAccordionPart(id, parent, count, json){ 
    //new string html2 is created and a bunch of stuff added
    //...
    html2 += "...."; 
    html2 += getAccordionBody(json);
    html2 += "</div></div></div></div>";
    return html2
}

function getAccordionBody(json){
//new string "html3" gets created
//...

 var url = standardUrl + "sources/" + encodeURIComponent(json.elementId) + "/streams";
 $.getJSON(url, function(data) {
    $.each(data, function(i, json) {
        html3 += "<li class='list-group-item'>";
        html3 += json.name;
        html3 += "</li>";
    });

}).done(function(){
    html3 += "</ul>";
    return html3;
});
var html1=”“;
$.getJSON(url、函数(数据){
$.each(数据、函数(i、json){
html1+=getAccordionPart(…);//为给定源创建手风琴
});
}).done(函数(){
html1+=”;
$('#elementList').html(html);
});
函数getAccordionPart(id、父级、计数、json){
//创建了新字符串html2,并添加了一些内容
//...
html2+=“…”;
html2+=getAccordionBody(json);
html2+=”;
返回html2
}
函数getAccordionBody(json){
//创建新字符串“html3”
//...
var url=standardUrl+“sources/”+encodeURIComponent(json.elementId)+“/streams”;
$.getJSON(url、函数(数据){
$.each(数据、函数(i、json){
html3+=“
  • ”; html3+=json.name; html3+=“
  • ”; }); }).done(函数(){ html3+=“”; 返回html3; });
    }

    我最终得到的是一个手风琴头,它的主体部分有“未定义”的部分, 因为在将html字符串添加到DOM之前,
    getAccordionBody()
    函数似乎不会返回

    我已经尝试过在我的两个
    $.getJSON
    调用中使用
    async=false
    $.getJSON
    更改为
    $.ajax
    ,这似乎解决了语句不能按我希望的顺序执行的问题,但速度非常慢,而且由于某些原因返回未定义的语句

    有什么建议吗?
    我错过了一些非常愚蠢的事情吗?

    您可以使用延迟/承诺模式,而不是使用同步呼叫

    • 您需要从生成手风琴函数返回承诺
    • 您需要排队生成手风琴函数调用
    • 然后在承诺得到解决时按顺序进行追加业务
    在将html字符串添加到DOM之前,getAccordionBody()函数似乎不会返回

    没错。您的操作方式有缺陷-您无法从
    done
    处理程序返回

    但是,您可以通过使用承诺来解决此问题。每个函数都会返回一个承诺,以便轻松链接,然后使用
    转换数据并获得新的承诺:

    $.getJSON(url).then(function(data){
        return $.when.apply($, $.map(data, function(i, json){
            return getAccordionPart(…); //creates the accordion for the given source
        }).then(function() {
            var html1 = "<div class='panel-group' id='manageAccordion'>";
            html1 += Array.prototype.join.call(arguments, "\n");
            html1 += "</div>";
            return html1;
        });
    }).done(function(html){
        $('#elementList').html(html);
    });
    
    function getAccordionPart(id, parent, count, json){ 
        return getAccordionBody(json).then(function(result) {
            var html2 = "…"; //new string html2 is created and a bunch of stuff added
            html2 += result;
            html2 += "</div></div></div></div>";
            return html2;
        });
    }
    
    function getAccordionBody(json) {
        var url = standardUrl + "sources/" + encodeURIComponent(json.elementId) + "/streams";
        return $.getJSON(url).then(function(data) {
            var html3 = "…"; //new string "html3" gets created
            $.each(data, function(i, json) {
                html3 += "<li class='list-group-item'>";
                html3 += json.name;
                html3 += "</li>";
            });
            html3 += "</ul>";
            return html3;
        });
    }
    
    $.getJSON(url).then(函数(数据){
    返回$.when.apply($,$.map)(数据,函数(i,json){
    return getAccordionPart(…);//为给定源创建手风琴
    }).然后(函数(){
    var html1=“”;
    html1+=Array.prototype.join.call(参数“\n”);
    html1+=”;
    返回html1;
    });
    }).done(函数(html){
    $('#elementList').html(html);
    });
    函数getAccordionPart(id、父级、计数、json){
    返回getAccordionBody(json){
    var html2=“…”;//创建了新字符串html2并添加了一组内容
    html2+=结果;
    html2+=”;
    返回html2;
    });
    }
    函数getAccordionBody(json){
    var url=standardUrl+“sources/”+encodeURIComponent(json.elementId)+“/streams”;
    返回$.getJSON(url).then(函数(数据){
    var html3=“…”;//创建新字符串“html3”
    $.each(数据、函数(i、json){
    html3+=“
  • ”; html3+=json.name; html3+=“
  • ”; }); html3+=“”; 返回html3; }); }
    您必须首先收集全局数组中“getAccordionPart”和“getAccordionBody”(例如:encodeURIComponent(json.elementId))所需的所有内容。例如:

    var arrIds = [];
    
    $.getJSON(url, function(data){
    $.each(data, function(i, json){
        arrIds.push(encodeURIComponent(json.elementId))//collect everything which is required for "getAccordionPart" and "getAccordionBody"
    });
    
    然后迭代这个集合,并在任何全局变量中收集这些ID的一致体的所有数据

    var bodyData = {};
    $.each(arrIds, function(){
    var url = standardUrl + "sources/" + this + "/streams";
    $.getJSON(url, function(data) {
        bodyData[this] = data;//collect all the Data for accordian body of these ids
    }});
    
    在getAccordionPart中也做一些小更改,如:

    function getAccordionPart(id, parent, count, /*json*/ elementId){ 
    //new string html2 is created and a bunch of stuff added
    //...
    html2 += "...."; 
    html2 += getAccordionBody(elementId);
    html2 += "</div></div></div></div>";
    return html2
    }
    
    最终代码为:

    var arrIds = [];
    
    $.getJSON(url, function(data){
    $.each(data, function(i, json){
        arrIds.push(encodeURIComponent(json.elementId))//collect everything which is required for "getAccordionPart" and "getAccordionBody"
    });
    
    var bodyData = {};
    $.each(arrIds, function(){
    var url = standardUrl + "sources/" + this + "/streams";
    $.getJSON(url, function(data) {
        bodyData[this] = data;//collect all the Data for accordian body of these ids
    }});
    
    function getAccordionPart(id, parent, count, /*json*/ elementId){ 
        //new string html2 is created and a bunch of stuff added
        //...
        html2 += "...."; 
        html2 += getAccordionBody(elementId);
        html2 += "</div></div></div></div>";
        return html2
        }
    
    function getAccordionBody(/*json*/ elementId){
    //new string "html3" gets created
    //...
    
     var data = bodyData[elementId];
        $.each(data, function(i, json) {
            html3 += "<li class='list-group-item'>";
            html3 += json.name;
            html3 += "</li>";
        });
    html3 += "</ul>";
        return html3;
    }
    
    $.each(arrIds , function(){
        html1 += getAccordionPart(,,,this); //creates the accordion for the given source
    });
    
    var arrIds=[];
    $.getJSON(url、函数(数据){
    $.each(数据、函数(i、json){
    arrIds.push(encodeURIComponent(json.elementId))//收集“getAccordionPart”和“getAccordionBody”所需的所有内容
    });
    var bodyData={};
    $.each(arrIds,function(){
    var url=standardUrl+“sources/”+this+“/streams”;
    $.getJSON(url、函数(数据){
    bodyData[this]=data;//收集这些ID的一致主体的所有数据
    }});
    函数getAccordionPart(id、父级、计数、/*json*/elementId){
    //创建了新字符串html2,并添加了一些内容
    //...
    html2+=“…”;
    html2+=getAccordionBody(elementId);
    html2+=”;
    返回html2
    }
    函数getAccordionBody(/*json*/elementId){
    //创建新字符串“html3”
    //...
    var data=bodyData[elementId];
    $.each(数据、函数(i、json){
    html3+=“
  • ”; html3+=json.name; html3+=“
  • ”; }); html3+=“”; 返回html3; } $.each(arrIds,function(){ html1+=getAccordionPart(,,this);//为给定源创建手风琴 });
    最好在服务器上生成html。因为它不需要来自客户端的任何用户输入,并且在循环中。因此,在服务器上生成html字符串将是更好的设计
    $.each(arrIds , function(){
        html1 += getAccordionPart(,,,this); //creates the accordion for the given source
    });
    
    var arrIds = [];
    
    $.getJSON(url, function(data){
    $.each(data, function(i, json){
        arrIds.push(encodeURIComponent(json.elementId))//collect everything which is required for "getAccordionPart" and "getAccordionBody"
    });
    
    var bodyData = {};
    $.each(arrIds, function(){
    var url = standardUrl + "sources/" + this + "/streams";
    $.getJSON(url, function(data) {
        bodyData[this] = data;//collect all the Data for accordian body of these ids
    }});
    
    function getAccordionPart(id, parent, count, /*json*/ elementId){ 
        //new string html2 is created and a bunch of stuff added
        //...
        html2 += "...."; 
        html2 += getAccordionBody(elementId);
        html2 += "</div></div></div></div>";
        return html2
        }
    
    function getAccordionBody(/*json*/ elementId){
    //new string "html3" gets created
    //...
    
     var data = bodyData[elementId];
        $.each(data, function(i, json) {
            html3 += "<li class='list-group-item'>";
            html3 += json.name;
            html3 += "</li>";
        });
    html3 += "</ul>";
        return html3;
    }
    
    $.each(arrIds , function(){
        html1 += getAccordionPart(,,,this); //creates the accordion for the given source
    });