Javascript和JQuery同步执行

时间:2018-12-07 10:14:51

标签: javascript jquery

我有一个函数,如果加载了json文件,该函数会附加一些元素:

function loadNdraw(title, id){

    $("#containerCharts").html("");

    var date = $("#dateChart");

    var jqJSON = $.getJSON("charts/" + id + "/" + date.val() + ".json");

    jqJSON.done(

        function(data){

            $("#containerCharts").append(
                "<div class='divStandard'>"
                    + "<div class='titleChart'>"
                        + "<div style='float: left;'>" + title + "</div>"
                        + "<div style='float: right;'>" + data.lastUpdate +"</div>"
                        + "<div style='clear: both;'></div>"
                    + "</div>"
                    + "<center><div id='" + id + "' class='bodyChart'></div></center>"
                + "</div>"
            );

        }

    );

}

我多次调用此函数

loadNdraw("A", "a");
loadNdraw("B", "b");
loadNdraw("C", "c");
loadNdraw("D", "d");

我的问题是它没有按此顺序加载。

每次加载页面时,A,B,C,D的顺序都是随机的。

如何强制按顺序加载它?

我不想对json进行排序。

3 个答案:

答案 0 :(得分:3)

您可以在jquery中使用.promise()函数

function loadNdraw(title, id){

    var dfd = jQuery.Deferred();

    $("#containerCharts").html("");

    var date = $("#dateChart");

    var jqJSON = $.getJSON("charts/" + id + "/" + date.val() + ".json");

    jqJSON.done(

        function(data){

            $("#containerCharts").append(
                "<div class='divStandard'>"
                    + "<div class='titleChart'>"
                        + "<div style='float: left;'>" + title + "</div>"
                        + "<div style='float: right;'>" + data.lastUpdate +"</div>"
                        + "<div style='clear: both;'></div>"
                    + "</div>"
                    + "<center><div id='" + id + "' class='bodyChart'></div></center>"
                + "</div>"
            );

        }

    );

    dfd.resolve(true);

}

然后您可以简单地致电

$.when( loadNdraw("A", "a") ).then(
  $.when( loadNdraw("B", "b") ).then(
  //Some code 
  );
);

您可以根据需要简单地使用.promise

答案 1 :(得分:3)

您可以使用JavaScript promise来做到这一点。

function loadNdraw(title, id){

    return new Promise(function (resolve, reject) {
        $("#containerCharts").html("");

        var date = $("#dateChart");

        var jqJSON = $.getJSON("charts/" + id + "/" + date.val() + ".json");

        jqJSON.done(

            function(data){
                var html = "<div class='divStandard'>"
                    + "<div class='titleChart'>"
                        + "<div style='float: left;'>" + title + "</div>"
                        + "<div style='float: right;'>" + data.lastUpdate +"</div>"
                        + "<div style='clear: both;'></div>"
                    + "</div>"
                    + "<center><div id='" + id + "' class='bodyChart'></div></center>"
                + "</div>";
                $("#containerCharts").append(html);

                resolve(html);

            }

        );
    });

}

用法:

1。

(async function () {
    await loadNdraw('A', 'a');
    await loadNdraw('B', 'b');
    await loadNdraw('C', 'c');
    await loadNdraw('D', 'd');
})();

2。

loadNdraw('A', 'a').then(function () {
    loadNdraw('B', 'b').then(function () {
        loadNdraw('C', 'c').then(function () {

        });
    });
});

答案 2 :(得分:2)

JSON脚本正在异步加载。回调触发的顺序不取决于您调用loadNdraw的顺序,而是取决于触发jqJSON.done的顺序。加载速度最快的文件将首先调用其jqJSON.done方法,依此类推。

如果您需要按顺序排列这些,则有一些选择:

  1. 加载所有结果后(或每次加载文件时)对HTML结构进行排序
  2. 通过在loadNdraw内调用jqJSON.done依次加载图表,这意味着图表B仅在完成A之后才开始加载-这可能会很多慢一点。
  3. 将结果填充到临时数据结构中,跟踪when所有请求已完成,然后根据该数据处理DOM操作。

在这种情况下,选项3似乎是最好的选择:

function loadNdraw(title, id) {
    $("#containerCharts").html("");

    var date = $("#dateChart");
    return $.getJSON("charts/" + id + "/" + date.val() + ".json");
}

var options = [
    { title: 'A', id: 'a' },
    { title: 'B', id: 'b' },
    { title: 'C', id: 'c' },
    { title: 'D', id: 'd' }
];

for (var option of options) {
    option.promise = loadNdraw(option.title, option.id);
}

$.when(...options.map(o => o.promise)).done(function(...results) {
    results.forEach(function(dataArray, idx) {
        var title = options[idx].title;
        var id = options[idx].id;

        $("#containerCharts").append(
            "<div class='divStandard'>"
                + "<div class='titleChart'>"
                    + "<div style='float: left;'>" + title + "</div>"
                    + "<div style='float: right;'>" + dataArray[0].lastUpdate +"</div>"
                    + "<div style='clear: both;'></div>"
                + "</div>"
                + "<center><div id='" + id + "' class='bodyChart'></div></center>"
            + "</div>"
        );
    });
});

请注意以下几点:

  1. $.when的参数是Thenables的列表-使用then方法的jqXHR之类的对象。您可以使用...spread运算符将其扩展为数组对象。
  2. $.when的回调将响应对象的列表作为其参数,按照发出请求的顺序。可以使用...rest参数语法将它们收集到数组中。