简体   繁体   中英

How do I extend JQuery's ajax done() method?

I have a jQuery ajax function like this:

jQuery.ajax({
            url : '/blabla',
            method : 'post',
            data: {
                bla : bla
            }
        }).done(function(data) {
            // do lots of stuff
        });

.. and I want to be able to add a check that the data passed into the done callback function doesn't have a session_timed_out value in it. Say I have many functions similar to the one above but they all do different things, but they ALL need to check if the session timed out first. Is there a proper way to extend done() so it initially checks for a timeout? I tried to do something like this but it failed:

var myAjax = function(options,callback){ 
    var defaults = {              
        done: function(data){  //hijack the success handler?
            if(check(data)){    
                callback(data); 
            }
        }
    };
    jQuery.extend(options,defaults);  
    return jQuery.ajax(options); 
}

When I use this extended function it works like before, meaning the check never gets called because it seems to be superseded by the done() callback in the actual implementation, which I guess makes sense. So I want to know if there is a way to "decorate" or extend done() function so it initially checks for the session timeout first. Or will I need to manually add this same session check to all of my ajax done's?

This snippet overrides the jQuery ajax method so you can add an extra check when it successfully returns.

(function($) {

    var yourCustomCheck = function(ajaxRes) {
        // Do whatever you need and return a boolean
    };

    var oldAjax = $.ajax;
    $.ajax = function(opts) {
        return $.Deferred(function() {
            var _def = this;

            oldAjax.call(this, opts).done(function(res) {
                console.log("this is done first");
                if(yourCustomCheck.call(this, res)) _def.resolve(res);
                else _def.reject("timeout");
            }).fail(function() {
                _def.reject();
            });
        })
    }

})(jQuery);

After this, you can use $.ajax() normally..

$.ajax({
    .....
}).done(function(res) {
    console.log("ok");
}).fail(function() {
    console.log("no ok");
});

Here is a jsfiddle with a working example: https://jsfiddle.net/jormaechea/kffyo7qL/1/

You could chain a timeout checker:

   jQuery.ajax({
        url : '/blabla',
        method : 'post',
        data: {
            bla : bla
        }
    }).then(timeoutCheck).then(function(data) {
        // do lots of stuff
    }, function(err) {
        // handle error
    });

    function timeoutCheck(data) {
        if (check(data)) {
           return data;
        } else {
           // return a rejected promise to turn fulfilled into reject
           return jQuery.Deferred.reject(new Error("timeout"));
        }
    }

Or, you could put this in your own ajax wrapper.

jQuery.ajaxT = function() {
     return jQuery.ajax.apply(jQuery, arguments).then(timeoutCheck);
}

jQuery.ajaxT(...).then(function(results) {
    // handle returned data here
    // the timeoutCheck has already been done
}, function(err) {
    // handle any errors here
});

Then, any ajax call you initiated with jQuery.ajaxT() would automatically have the timeoutCheck added to it's promise logic. If the ajax call succeeds and the timeout check passes, then the promise is fulfilled. If the ajax call succeeds and the timeout check fails, then the promise rejected.

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