开发者

jQuery UI Autocomplete: Aborting the request

开发者 https://www.devze.com 2023-03-14 21:23 出处:网络
I\'m using the callback version of the source option which performs an ajax request. I figure if a user types a bunch of letters in rapid succession before an ajax request completes, we should abort t

I'm using the callback version of the source option which performs an ajax request. I figure if a user types a bunch of letters in rapid succession before an ajax request completes, we should abort the old one and only use the new one. I'm assuming the URL version for the source parameter would do this automatically, but since I'm using a custom callback, I'd have to do that manually.

So here's what I've got:

$('#myselector').autocomplete({
    source: function(request, response) {
        var data = {};
        if($(this).data('xhr')) {
            console.log('aborting...');
            $(this).data('xhr').abort();
        }
        // *snip* add some stuff to data
        $(this).data('xhr', $.ajax({
            url: '/ajax/major_city',
            dataType: 'json',
            data: data,
            success: function(data, textStatus, $xhr) {
                response(data);
            },
            complete: function($xhr, textStatus) {
                console.log(textStatus);
     开发者_开发问答           if(textStatus === 'abort') {
                    console.log('aborted!');
                    response([]);
                }
            }
        }));
    },
// ....

So, whenever the "source" callback is triggered, it checks if the XHR element exists for that input (will be undefined the first time), and if so, aborts it (side question: how can I check if the request is complete? No sense trying abort requests that have already completed).

But the docs say:

It's important when providing a custom source callback to handle errors during the request. You must always call the response callback even if you encounter an error. This ensures that the widget always has the correct state.

So, towards the bottom of my code you'll see that I (attempt to) check if the request has been aborted, and if so, I return an empty list. But that "aborted!" log never seems to be called. It always says "success" even when it gets aborted. Why's that?


Edit: Just tried outputting $(this).data('xhr').readyState. It never seems to be less than 4 which suggests to me that source isn't called again until the last request returns a response. Which is a shame, because we could abort the requests early and speed up the response time a bit...


bdparrish has the right idea

Increase the time the plugin waits before sending the request:

$( ".selector" ).autocomplete({ delay: 500 }); //default is 300

This way you will only send the request once you suspect the user has finished typing. It's better to make less http requests than make many and cancel them.

-Lededje


Is there a reason that you can't set the time interval to wait for the user to "seem" like they are finished typing? The 'delay' option sets the milliseconds that it will wait after the last letter is typed before searching.

Also, the response would still be a success even if you return 'abort' from the server. because the request did not error out on the server. you return the value 'abort' i am assuming.

0

精彩评论

暂无评论...
验证码 换一张
取 消