Jquery delayed turn failure into success

So, when using deferred jQuery and $.when to load many objects in parallel.

 $.when( a.ajax(), b.ajax(), c.ajax() ).then( //do something when all are complete complete(); ); 

Now b.ajax() will sometimes fail, but I really don't care. I just want to wait until all calls are completed before calling complete ().

Unfortunately, as soon as b fails, when() rejects and never starts the then() callback. This is the expected AFAIK behavior for $.when() , however the pre-trial suit is for me in this case.

I really want to say:

 $.when( a.ajax(), b.ajax().fail(return success), c.ajax() ).then(...) 

Or maybe there is another way to use when() or a more suitable construct?

+6
source share
4 answers

So I figured this out at the end, see my answer to someone else with the same problem:

how to trick jqXHR to succeed always

The lonesomeday response was neat, but not quite what I was after.

+1
source

If you want to capture the failure of a promise and turn it into success, you can use failFilter then to return the allowed promises, for example like this:

 deferredCall.then(function(answer) { // this is success. you might transform the answer here. return transformed; }, function() { // this is a fail. you might resolve the fail with an empty object. return $.Deferred().resolve({}).promise(); }); 

Doing this ensures that the chain can continue to fail without interruption.

So, for your example, you can do this:

 $.when([ a.ajax(), b.ajax().then(function(answer) { return answer; }, function() { return $.Deferred().resolve({}).promise(); }), c.ajax() ]).then(function(results) { // etc. }); 

Example 2. In my applications, I sometimes use then to obtain relational data for a specific object and allow the possibility of 404 to indicate that there is no such relation exists:

 getEntity(id).then(function(entity) { return getAssociation(id).then(function(association) { entity.association = association; return entity; }, function() { entity.association = null; return $.Deferred().resolve(entity).promise(); }); }).done(function(entity) { // etc. }); 

Note. Older answers suggest using the pipe method. This method is deprecated from jQuery 1.8.

+5
source

Here is something better than hacking failure to succeed.

A little-known fact, $ .when () will call then () immediately if any of the parameters fail. This is by design. To quote the documentation:

http://api.jquery.com/jQuery.when/

In the case of multiple deferrals, when one of the Deferred is rejected, jQuery.when immediately launches failCallbacks for its Deferred host. Please note that some of the Deferrals may still remain unresolved at this point. If you need to perform additional processing for this case, for example, to cancel any pending ajax requests, you can keep the links to the underlying jqXHR objects in close and check / cancel them in failCallback.

There is actually no built-in way to wait until all of them are completed regardless of their success / failure status.

So, I created for you $ .whenAll () :) It always waits until they all resolve, one way or another:

http://jsfiddle.net/InfinitiesLoop/yQsYK/

+3
source

You can easily build $.onFailSucceed by wrapping the $.Deferred object:

 $.onCompleteSucceed = function(oldDfd) { var newDfd = $.Deferred(); oldDfd.always(newDfd.resolve); return newDfd.promise(); } 

Then you can wrap the appropriate calls in this method:

 $.when( a.ajax(), $.onCompleteSucceed(b.ajax()), c.ajax() ).then(...) 
+1
source

Source: https://habr.com/ru/post/889913/


All Articles