Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reuse jQuery.post() / jQuery.Deferred() object

the simplest example of what I'm looking for is this:

var messageLoader = $.post("api/user/messages", {api:data})

messageLoader.done(function(data){
   //do something 
});

This works brilliantly, but only once. If I want to update the data, I have to redefine everything.

I can't seem to find any call for the Deferred Object that let's me restart it. i.e. messageLoader.redo(), which ideally would re-do the POST request, and subsequently call the same "done" handler without me having to re-define it.

I could put it all in a function and simply call that function again, but that's not what I'm looking for, because I would further want to do this:

var messageLoader = $.post("api/user/messages", {api:data})
var friendRequestLoader = $.post("api/user/friendrequests", {api:data})

$.when(messagesLoader, friendRequestLoader)
    .done(function (messages, friendRequests) {
        // update display of messages and friend requests
        // attach Handlers
    });

$("#updateMessages").click(function(){
    messageLoader.redo() // This doesn't exist
})

The idea is that clicking $("#updateMessages") would re-do just that request, then the $.when() handler would use the new messageLoader data, and the original friendRequestLoader data.

I've looked in the docs for something like this but haven't found anything. Perhaps someone here knows if it exists, or a way to accomplish the same thing.

like image 555
synaptomy Avatar asked Dec 05 '12 21:12

synaptomy


1 Answers

I'm pretty sure the Deferred class just isn't designed to work the way you want, because they're intended to be one-time use objects. I even sat in on a whole session on Deferreds at jQueryConf, and re-using them wasn't even mentioned.

Furthermore, as you can see from the Deferred API page:

http://api.jquery.com/category/deferred-object/

there is no restart method. You might be able to manually change the properties of a Deferred to simulate "restarting" it, but really I think you should make your own class at this point, as you're really looking for something Deferred doesn't offer.

You have to keep in mind, Deferred is designed so that you can say "hey Deferred, go do something" (new Deferred().when(something)), and then you can say "hey Deferred, when that's done do X" (deferred.then(x)). Now, when you say "when that's done", ie. when you make a .then call, the Deferred can be in two states: done, or not, but the call works in either case (if it's done it resolves immediately, otherwise it waits to be triggered).

Now, if a Deferred could have a third state ("done but restarted"), the .then call wouldn't know what to do: does "done but restarted" mean that it should fire it's thens, or not? The answer depends on whether you made the .then call before or after the restart call, and as you're hopefully seeing that all has the potential to get rather complicated (especially if you allow for multiple restarts).

Rather than deal with all that (none of which was needed for $.ajax) the jQuery folks went with the (comparatively simple) current Deferred implementation, and I think it was the right call on their part.

like image 162
machineghost Avatar answered Oct 19 '22 05:10

machineghost