-->

Kill Ajax Session Outside of Originating Function

2019-09-14 21:37发布

问题:

I have an AJAX function I'd like to kill, but it is outside of the function. Take a look:

function waitForMsg(){

       var heartbeat = $.ajax({
            type: "GET",
            url: "includes/push_events.php",
            tryCount : 0,
            retryLimit : 3,
            async: true,
            cache: false,
            // timeout: 500,

            success: function(data){ 
                console.log(data);
                if(data){
                    if(data.current_date_time){
                        updateTime(data.current_date_time);
                    }
                    if(data.color){
                        console.log("Receiving data");
                        displayAlert(data.color, data.notification_message, data.sound, data.title);
                    }
                    if(data.user_disabled){
                        console.log("Receiving data");
                        fastLogoff();
                        checkDisabled();
                    }       

                }
                setTimeout(
                    waitForMsg,
                    5000 
                );
            },


            error: function(data){
                if (data.status == 500) {
                    console.log("Connection Lost to Server (500)");
                        $.ajax(this);
                } else {
                    console.log("Unknown Error. (Reload)");
                        $.ajax(this);
                }

            },

            dataType: "json"

        });
    };

    // Detect browser open.


    $(document).ready(function(){

        // window.onunload = function(){alert('closing')};

        // mainmode();

        $('#alertbox').click(function(){
                $('#alertbox').slideUp("slow");
        });

        $(document).ready(function(){


    $('#alertbox').click(function(){
            $('#alertbox').slideUp("slow");
    });


    // Check focal point
    var window_focus = true;


           $(window).focus(function() {
                window_focus = true;
                console.log('Focus');
            });

            $(window).blur(function() {
                window_focus = false;
                console.log('Blur');
            });


    setInterval(function(){
        if(window_focus == true){
            console.log('in focus');
            waitForMsg();
        }else{
            console.log('out of focus');
            heartbeat.abort();
        }

    }, 5000);
});




    });

If you notice, the ajax is outside of the document.ready. I am trying to kill the ajax calls if the user goes to a different window, then restart the calls once the return to the window. The start works, but if the user goes away from the window, it gives me the "heartbeat is not defined". Obviously this is because its outside of that function. Any work arounds?

回答1:

I'd refactor a bit the code to avoid the usage of setInterval and clean up a bit the code.

You can abstract the logic in an object, let's say Request. You can add two methods to resume and stop which will handle the status of the underlying AJAX request.

var Request = function(options){
    var request = this, xhr = null, aborted = false;

    /* Resumes the operation.
     * Starts a new request if there's none running.
     */
    request.resume = function() {
        aborted = false;
        request.retry();
    };

    /* Retry loop.
     */
    request.retry = function(){
        if(!xhr) {
            xhr = $.ajax(options).done(function(){
                request.destroy();
                !aborted && setTimeout(function(){
                    request.retry();
                }, options.timeout);
            });
        }
    };

    /* Aborts the current operation.
     */
    request.abort = function(){
        aborted = true;
        if(xhr) xhr.abort();
        request.destroy();
    };

    /* Destroy.
     */
    request.destroy = function(){
        xhr = null;
    };

    return request;
};

Now, you can drop the setInterval.

$(function () {
    var request = new Request({
        type: "GET",
        url: "includes/push_events.php",
        timeout: 5000,
        success: function(data){ 
            /* Success handler */
        },
        error: function(data){
            /* Error handler */
        },
        dataType: "json"
    });

    $(window).focus(function () {
        request.resume();
    }).blur(function () {
        request.abort();
    });

    request.resume();
});

The Request constructor receives the $.ajax options which should contain an additional timeout parameter that specifies the delay between requests.



回答2:

You need to stop further request after window.blur. restart request after window.focus.

Modified code

var setTimeoutConst;
function waitForMsg(){
        if(!window_focus){
             return; //this will stop further ajax request
        }
       var heartbeat = $.ajax({
            type: "GET",
            url: "includes/push_events.php",
            tryCount : 0,
            retryLimit : 3,
            async: true,
            cache: false,
            // timeout: 500,

            success: function(data){ 
                console.log(data);
                if(data){
                    if(data.current_date_time){
                        updateTime(data.current_date_time);
                    }
                    if(data.color){
                        console.log("Receiving data");
                        displayAlert(data.color, data.notification_message, data.sound, data.title);
                    }
                    if(data.user_disabled){
                        console.log("Receiving data");
                        fastLogoff();
                        checkDisabled();
                    }       

                }
                setTimeoutConst= setTimeout(waitForMsg,5000);
            },
            error: function(data){
                if (data.status == 500) {
                    console.log("Connection Lost to Server (500)");
                       // $.ajax(this);
                } else {
                    console.log("Unknown Error. (Reload)");
                        //$.ajax(this);
                }
                setTimeoutConst= setTimeout(waitForMsg,5000); // continue sending request event if last request fail
            },
            dataType: "json"

        });
    };

var window_focus = true;
$(document).ready(function(){

    $('#alertbox').click(function(){
        $('#alertbox').slideUp("slow");
    });

    $('#alertbox').click(function(){
            $('#alertbox').slideUp("slow");
    });
    // Check focal point
     $(window).focus(function() {
        if(window_focus ){return}
        window_focus = true;
        waitForMsg(); 
        console.log('Focus');
    });
   $(window).blur(function() {
          if(!window_focus ){return}
        clearTimeout(setTimeoutConst);
        window_focus = false;
        console.log('Blur');
    });

    waitForMsg();            
});