I've just begun with Wordpress and I'm working on an AJAX-based search form.

The logic is this: on each keystroke, the previous AJAX request is aborted (if exists), and a new one is issued. For some reason it seems that on serverside the function that returns the search results executes sychronously, so if I type hello, the function is called for h, he, hell and so on, which is fine, but the thing is they're executing as if they're in a queue, so each new call is waiting for the previous ones to finish. I've noticed this by using a dummy log function which goes like this

function mylog($str, $outfile="woo_log.txt", $append=true) {
    $flags = 0;
    $str = time()." ".$str;

    if($append)
        $flags = FILE_APPEND;
    file_put_contents("X:\\path\\$outfile", $str."\n", $flags);
}

After calling the log function a few places inside my function (which mainly loops a few times), the log goes like this:

*note: hello is being typed within 1-2 seconds interval

1514021040 search: he
1514021041 5a3e20b02c4a8 Total: 71081
1514021041 5a3e20b02c4a8 1
1514021043 5a3e20b02c4a8 2
1514021044 5a3e20b02c4a8 3
1514021045 5a3e20b02c4a8 4
1514021047 5a3e20b02c4a8 5
1514021047 search: hel
1514021048 5a3e20b795fc4 Total: 52360
1514021048 5a3e20b795fc4 1
1514021050 5a3e20b795fc4 2
1514021051 5a3e20b795fc4 3
1514021052 5a3e20b795fc4 4
1514021065 5a3e20b795fc4 5
1514021065 search: hell
1514021067 5a3e20c9e0037 Total: 31836
1514021067 5a3e20c9e0037 1
1514021068 5a3e20c9e0037 2
1514021069 5a3e20c9e0037 3
1514021070 5a3e20c9e0037 4
1514021072 5a3e20c9e0037 5
1514021072 search: hello
1514021076 5a3e20d08d505 Total: 78401
1514021076 5a3e20d08d505 1
1514021082 5a3e20d08d505 2
1514021083 5a3e20d08d505 3
1514021084 5a3e20d08d505 4
1514021088 5a3e20d08d505 5
1514021089 search: hello
1514021090 5a3e20e1288e3 Total: 78404
1514021090 5a3e20e1288e3 1
1514021091 5a3e20e1288e3 2
1514021092 5a3e20e1288e3 3
1514021093 5a3e20e1288e3 4
1514021098 5a3e20e1288e3 5

As you can see there's the timestamp and an unique id that is generated at the beginning of the function block, and the logged string. I'm live watching the log file and it seems each call waits for the other one to finish; also the response is received on clientside(browser) when the last call finishes.

The function is hooked like this:

add_action('wp_ajax_nopriv_megashop_tt_ajax_pro_search', 'megashop_tt_ajax_pro_search_amazon');
add_action('wp_ajax_megashop_tt_ajax_pro_search', 'megashop_tt_ajax_pro_search_amazon');

Here is an excerpt from the JS code

  currentRequest = jQuery.ajax({
        url : screenReaderText.ajaxurl,
        type : 'post',
        data : {
            action : 'megashop_tt_ajax_pro_search',
            keyword : input_val,
            category : category
        },
        beforeSend : function()    {
            if(currentRequest != null) {
                currentRequest.abort();
                console.log("aborted on: "+input_val);
            }
            if($('body').hasClass('rtl')){
                $('#tt_pro_search_input').css({
                    'background-image': 'url('+ajax_search_loader+')', 
                    'background-repeat': 'no-repeat', 
                    'background-position': '15px center'
                });
            }else{
                $('#tt_pro_search_input').css({
                    'background-image': 'url('+ajax_search_loader+')', 
                    'background-repeat': 'no-repeat', 
                    'background-position': 'right center'
                });
            }               

            $('.tt_ajax_search_results').hide();
        },
        success : function( response ) 
        {
            response = response.trim();
            ...etc

So the question is, why the function isn't called in an async manner? What am I missing? It could be a wordpress internal thing?

UPDATE

I went on calling directly the script by ajax, without hooking through wordpress and everything works as expected. So the problem might have to do with wordpress's bootstrap process, as @JacobPeattie specified in the comments, combined with my machine's poor performance.

  • 1
    Well each request is sent in the order you make them, and they're being handled in that order. I'm not sure what you're expecting to happen? You can't abort an AJAX request, you can only stop listening for a response, so they're all going to get processed as they are sent. Aborting the request is why you only get the last response back. The delay you're seeing isn't it waiting for the previous request to finish, it's just the time it takes WordPress to boot up for each request. What you should be doing is holding off sending any request at all until a pause in typing. – Jacob Peattie Dec 23 '17 at 10:06
  • That's true, but as you see, when I'm typing "hello" (there's 1-2 seconds delay between first and last ajax call - I'm also testing this on localhost, so I can say the network latency is pretty low), the delay between first and last function call on server is about 50 seconds, which kinda doesnt make sense – ngwdaniel Dec 23 '17 at 10:27

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.