then 中的函数在结束之前被调用

Function in then is being called before when ends

我不明白为什么 JQuery 不等到一个函数结束。我正在使用 when().then() 条款和第一个函数 returns AJAX 调用。

$('#id_language_from').on('change', function () {
        blockLoader();
        var rtl = refreshTargetLanguages();
        var rstl = refreshSummaryTargetLanguages();
        $.when(rtl).then(rstl).then(unblockLoader);

    });

问题是 rstl 必须等到 rtl 结束,但实际上并没有。

CHROME CONSOLE:(RSTL 应该在 DONE SUCCESS RTL 之后)

RTL
RSTL
...
DONE SUCCESS RTL

RTL 和 RSTL

function refreshTargetLanguages() {
    console.log('RTL');
    var language_id = $('#id_language_from').val();
    if (language_id != '') {
        var request_url = '/orders/ajax/get-languages-to-exclude/';
        return $.ajax({
            url: request_url,
            method: 'post',
            data: {'language_id': language_id},
            success: function (data) {
                $('.class_target_languages').show();

                window.changeunbind = 1;

                $('.target_language_choice.active').trigger('click');

                window.changeunbind = 0;

                $.each(data, function (key, value) {
                    hideTargetLanguageById(key);
                });
                console.log('DONE SUCCESS RTL')
            }
        })
    } else {
        console.log('call HATL');
        return hideAllTargetLanguages();
    }
}

function refreshSummaryTargetLanguages() {
    console.log('RSTL');
    var summ_ul_targ_langs = $('#summary_target_languages > ul');
    $('#id_summary_price').text('');
    var active_languages = $('.target_language_choice.active');
    console.log(active_languages);
    var words_count = $('#id_word_count').text();
    if (active_languages.length < 1 || !Boolean(words_count)) {
        console.log('emtpy');
        return summ_ul_targ_langs.find('ul').empty();

    }
    blockLoader();
    var active_languages_ids = [];
    active_languages.each(function () {
        active_languages_ids.push($(this).attr('data-pk'));
    });
    var source_language_id = $('#id_language_from').val();

    var summ_ul_targ_langs = $('#summary_target_languages > ul');
    summ_ul_targ_langs.empty();
    if ((words_count == '') || (words_count == 'NA')) {
        return
    }
    return $.post('/orders/languages-prices/', {
        'word_count': words_count,
        'language_from_id': source_language_id,
        'languages_to_ids': active_languages_ids
    }).done(function (response) {
        var estimated_price = response['estimated_price'];
        var items = response['items'];
        $.each(items, function (_, item) {
            var name = item['name'];
            var id = item['id'];
            var price = item['price'];
            var price_per_word = item['price_per_word'];
            summ_ul_targ_langs.append('<li>' + name + ': ' + price_per_word + ' x ' + words_count + ' = ' + price + '</li>');
        });
        $('#id_summary_price').text(estimated_price + ' €');
        console.log('DONE RSTL')


    });

}

你知道问题出在哪里吗?

编辑

根据 Anthony 的回答,我已将 RTL 更改为:

function refreshTargetLanguages() {
    console.log('RTL');
    var language_id = $('#id_language_from').val();
    var deferred = $.Deferred();
    if (language_id != '') {
        var request_url = '/orders/ajax/get-languages-to-exclude/';
        $.ajax({
            url: request_url,
            method: 'post',
            data: {'language_id': language_id}
        }).then(function(data){
            $('.class_target_languages').show();

            window.changeunbind = 1;

            $('.target_language_choice.active').trigger('click');

            window.changeunbind = 0;

            $.each(data, function (key, value) {
                hideTargetLanguageById(key);
            });
            console.log('DONE SUCCESS RTL');
            deferred.resolve();
        }, function(error){
            deferred.reject(error);
        });
    } else {
        console.log('call HATL');
        hideAllTargetLanguages();
        deferred.resolve();
    }
    return deferred.promise();
}

这也没有帮助...

您应该将函数传递给 then(),但您在 ajax

之前执行该函数

var rstl = refreshSummaryTargetLanguages()

应该是

var rstl = refreshSummaryTargetLanguages

或者您可以将所有内容都放在一行中 refreshTargetLanguages().then(refreshSummaryTargetLanguages).then(unblockLoader);

可能与问题无关,我也会稍微修改 refreshTargetLanguages 以便它 returns 一个在记录 console.log('DONE SUCCESS RTL') 之前不会得到解决的承诺

function refreshTargetLanguages() {
    console.log('RTL');
    var language_id = $('#id_language_from').val();
    var deferred = $.Deferred();
    if (language_id != '') {
        var request_url = '/orders/ajax/get-languages-to-exclude/';
        $.ajax({
            url: request_url,
            method: 'post',
            data: {'language_id': language_id}
        }).then(function(data){
            $('.class_target_languages').show();

            window.changeunbind = 1;

            $('.target_language_choice.active').trigger('click');

            window.changeunbind = 0;

            $.each(data, function (key, value) {
                hideTargetLanguageById(key);
            });
            console.log('DONE SUCCESS RTL');
            deferred.resolve();
        }, function(error){
            deferred.reject(error);
        });
    } else {
        console.log('call HATL');
        hideAllTargetLanguages();
        deferred.resolve();
    }
    return deferred.promise();
}