简体   繁体   中英

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

I've done a web page that has to make the use wait a loooong time before getting the answer.

When the user clicks on "Generate" (complex stuff), i do a slow slideUp() of the main div and immediately after that, I launch my "background" AJAX call:

$('#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);
})".

Everything works fine... only when the answer takes longer than the "hide" animation. If the answer is fast, the we can see the content of the maindiv being replaced.

How do you deal with that?

You make sure both the animation and the ajax call has completed before you replace the content

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

This way the ajax call starts right away without having to wait for a callback, and the promises makes sure both have completed before the callback for $.when is called.

Here's my final working code, thanks to 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);
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM