$.when() with array of Deferreds not calling done action

可紊 提交于 2019-12-25 04:14:38

问题


I am trying to use a variable set of deferred functions in an array along with $.when(). These functions fetch data from the server and render it in the DOM. After all these are done, some scripts are loaded and a couple post-load actions are performed.

Here is what I am using:

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);
}

The problem is that loadPostGamesLoadData is never being called.

Both loadGames and loadPlayoffs return promises:

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.");
        }
    });
}

回答1:


You're creating the deferred objects incorrectly; indeed, you shouldn't be creating them at all. The function accepted by $.Deferred is a factory function run just before $.Deferred returns which receives the new deferred object as an argument (so you can attach handlers to it). (Details in the API docs.) That's not what loadGames and such do at all; they return a deferred object. So you end up with deferred objects that nothing ever settles.

Since they already have deferred objects from $.ajax, which you're returning, just use those functions directly:

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

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

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



回答2:


Drop the Deferred calls, as $.ajax already returns a deferred.

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

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

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


来源:https://stackoverflow.com/questions/41376908/when-with-array-of-deferreds-not-calling-done-action

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!