带有Deferreds数组的$ .when()没有调用done动作

时间:2016-12-29 09:39:01

标签: javascript jquery ajax jquery-deferred

我试图在数组和$.when()中使用一组变量延迟函数。这些函数从服务器获取数据并在DOM中呈现它。完成所有这些操作后,将加载一些脚本并执行几个后加载操作。

以下是我正在使用的内容:

function loadAllGames(updateGames, updatePlayoffs) {
    var deferredLoads = [];
    if (updateGames !== false)
        deferredLoads.push($.Deferred(loadGames));

    if (updatePlayoffs !== false)
        deferredLoads.push($.Deferred(loadPlayoffs));

    $.when.apply($, deferredLoads).done(loadPostGamesLoadData);
}

问题是永远不会调用loadPostGamesLoadData

loadGamesloadPlayoffs都会返回承诺:

function loadGames() {
    $.get('{% url wave_spinner_template %}', {message: 'Loading games...'}, function (data) {
        $('#weeks').html(data);
    });

    return $.ajax({
        url: "{% url weeks season.id %}",
        success: function (data) {
            $('#weeks').html(data);
        },
        error: function () {
            console.log("Error loading games.");
        }
    });
}

function loadPlayoffs() {
    $.get('{% url wave_spinner_template %}', {message: 'Loading playoffs...'}, function (data) {
        $('#playoffs').html(data).children('.spinner-container').addClass('border-top');
    });

    return $.ajax({
        url: "{% url playoffs season.id %}",
        success: function (data) {
            var $playoffs = $('#playoffs');
            if (!$playoffs.length) {
                $playoffs = $('<div>', {id: 'playoffs'});
                $('#weeks').after($playoffs);
            }
            $playoffs.html(data);
        },
        error: function () {
            console.log("Error loading playoffs.");
        }
    });
}

2 个答案:

答案 0 :(得分:1)

删除Deferred次来电,因为$.ajax已经返回延期。

function loadAllGames(updateGames, updatePlayoffs) {
    var deferredLoads = [];
    if (updateGames !== false)
        deferredLoads.push(loadGames());

    if (updatePlayoffs !== false)
        deferredLoads.push(loadPlayoffs());

    $.when.apply($, deferredLoads).done(loadPostGamesLoadData);
}

答案 1 :(得分:0)

您错误地创建了延迟对象;实际上,你根本不应该创造它们。 $.Deferred接受的函数是在$.Deferred返回之前运行的工厂函数,它接收新的延迟对象作为参数(因此您可以将处理程序附加到它)。 (Details in the API docs.)那不是loadGames这样做的事情;他们返回一个延迟对象。所以你最终会得到任何无法解决的延迟对象。

由于已经已将$.ajax中的对象延迟退回,您只需直接使用这些功能:

function loadAllGames(updateGames, updatePlayoffs) {
    var deferredLoads = [];
    if (updateGames !== false)
        deferredLoads.push(loadGames());
// ------------------------^^^^^^^^^^^

    if (updatePlayoffs !== false)
        deferredLoads.push(loadPlayoffs());
// ------------------------^^^^^^^^^^^^^^

    $.when.apply($, deferredLoads).done(loadPostGamesLoadData);
}