jQuery and AJAX: 反应太快怎么办?

jQuery and AJAX: how to deal with too fast responses?

我做了一个网页,必须让用户等待很长时间才能得到答案。

当用户点击 "Generate"(复杂的东西)时,我对主 div 进行缓慢的 slideUp() 操作,然后立即启动我的 "background" AJAX 电话:

$('#div-lol-generate-result').slideUp(4000);
$('#div-lol-generate-form').slideUp(3000);
$.ajax({
    url: '/long/api/call/that/takes/between/1/and/10/seconds',
    data: data,
    dataType: 'json',
    method: 'POST'
})
.done(function(result) {
    console.log('ok :');
    console.log(result);
    var monp=$('<p />');
    if (typeof(result.error)!='undefined') {
        for (var i in result.error) {
            monp.append(result.error[i]);
            monp.append('<br />');
        }
    } else if (typeof(result.story)!='undefined') {
        console.log(result.story.length);
        for (var i in result.story) {
            monp.append(result.story[i]);
            monp.append('<br />');
        }
    }
    monp.last().remove();
    $('#div-lol-generate-result').empty().append(monp).slideDown();
    });
})
.error(function(result) {
    console.log('Erreur :');
    console.log(result);
})".

一切正常... 仅当答案花费的时间比 "hide" 动画长 时。如果回答很快,我们可以看到 maindiv 的内容被替换了。

你是怎么处理的?

在替换内容之前确保动画和 ajax 调用都已完成

var promise1 = $('#maindiv').slideUp(4000).promise();

var promise2 = $.ajax({
                   url      : '/complexstuff',
                   data     : data,
                   dataType : 'json',
                   method   : 'POST'
               });

$.when.apply($, [promise1, promise2]).done(function(elem, data) {
    $('#maindiv').html(data.result).slideDown();
});

这样 ajax 调用会立即开始,而无需等待回调,并且承诺会确保在调用 $.when 的回调之前两者都已完成。

这是我最终的工作代码,感谢 adeneo

$(document).ready(function() {
    $('#div-lol-generate-result').hide();
    var sub=function() { return lol_submit(); };
    var lol_submit = function() {
        var data=$('#lol-generate-form').serialize();
        $('#lol-generate-form :input')
            .prop('disabled', 'disabled');
        $('#lol-generate')
            .unbind('click')
            .click(function(e) {
                e.preventDefault();
            });
        $.when(
            $('#div-lol-generate-result').slideUp(4000),
            $('#div-lol-generate-form').slideUp(3000),
            $.ajax({
                url: '/lol/json/story',
                data: data,
                dataType: 'json',
                method: 'POST'
            })
        )
        .then(function(a, b, c) {
            result=c[0];
            var monp=$('<p />');
            if (typeof(result.error)!='undefined') {
                for (var i in result.error) {
                    monp.append(result.error[i]);
                    monp.append('<br />');
                }
            }
            else if (typeof(result.story)!='undefined') {
                console.log(result.story.length);
                for (var i in result.story) {
                    monp.append(result.story[i]);
                    monp.append('<br />');
                }
            }
            monp.last().remove();
            $('#div-lol-generate-result')
                .empty()
                .append(monp)
                .slideDown();
        }, function(a, b, c) {
            /* should never happen
             * TODO: hide and all ask refresh
             */
            // a=xhr
            // b='failure'
            // c='Not Found'
        })
        .always(function(result) {
            $('#lol-generate-form :input').removeAttr('disabled');
            $('#lol-generate').click(sub);
            $('#lol-generate-form-input-summoner-name').focus().select();
            $('#div-lol-generate-form').slideDown();
        });
        return false;
    }
    $('#lol-generate-form').submit(sub);
    $('#lol-generate').click(sub);
});