0

I ran into the code block below...and I don't understand it. I understand promises perfectly in the sense of (and everything that goes with it):

deferred.then(successCb, errorCb);

However, the code below seems to have three callbacks(complete, fail, done) and I don't know where to begin looking - I can only guess an observable-like success, failure, finally pattern, but that doesn't seem to be the case.

I checked random questions like jQuery deferreds and promises - .then() vs .done() and some docs like here. The docs seem to imply that complete isn't even a thing and there are only always (runs whether promise succeeds or fails, on resolve), done('this will run if the $.get succeeds' - weird name for it), fail(fail) conditions.

 var promise = $.ajax({
    type: 'POST',
    url: 'www.foo.com',
    dataType: 'json',
    contentType: 'application/json; charset=utf-8',
    data: muhData
  });
  promise.complete(function(d) {
    console.debug("complete");
  }).fail(function(){
    console.error("failed!");
  }).done(function(d){
    console.log('Done');
  });

tl;dr: Wut code do?

VSO
  • 11,546
  • 25
  • 99
  • 187
  • If you downvote because it's obvious to you and I am missing something obvious - please throw a link to what I am missing here. – VSO Sep 29 '17 at 20:49
  • 4
    One should never downvote without commenting. It is antisocial behavior. – ideaboxer Sep 29 '17 at 20:50
  • 1
    Did you read those docs: http://api.jquery.com/jquery.ajax – ideaboxer Sep 29 '17 at 20:52
  • 1
    It's part of the ajax docs, not deferred. Scroll down to `complete`: http://api.jquery.com/jquery.ajax/ – JBC Sep 29 '17 at 20:54
  • Thanks guys. I am seeing I am seeing `complete`, `error`, and `success`, I am not seeing done anywhere - it seems to be deprecated. `you must use the success/error/complete callback options instead of the corresponding methods of the jqXHR object such as jqXHR.done().` - is that the case? – VSO Sep 29 '17 at 20:55
  • P.S. I don't use jQuery ever - that probably shows. – VSO Sep 29 '17 at 20:56

1 Answers1

2

.complete(), .done() and .fail() are all jQuery-specific implementations that do not follow promise standards. jQuery also supports .then() an in jQuery 3.x they attempted to make .then() be compliant with the promise standard. What I'd suggest you do is this:

 $.ajax({
    type: 'POST',
    url: 'www.foo.com',
    dataType: 'json',
    contentType: 'application/json; charset=utf-8',
    data: muhData
  }).then(function(d) {
    console.debug("complete");
  }, function() {
    console.error("failed!");
  });

Or, if you're forced to an older version of jQuery and want standard's compliant behavior, you can do this:

 Promise.resolve($.ajax({
    type: 'POST',
    url: 'www.foo.com',
    dataType: 'json',
    contentType: 'application/json; charset=utf-8',
    data: muhData
  })).then(function(d) {
    console.debug("complete");
  }).catch(function() {
    console.error("failed!");
  });

This casts/absorbs a jQuery promise into a standard promise so you can then use standard .then() and .catch() logic with it and have no surprises on how it works.


Here's more info on .complete(), .done() and .fail() from the jQuery docs:

.complete() is deprecated and .always() should be used instead. This is called whether the promise fulfills or rejects (e.g. it's always called).

.fail() is analagous to .catch() in that it gets called when the promise rejects (though not identical in all respects).

.done() is analagous to the first argument passed to .then() in that it gets called when the promise fulfills.

Honestly, I don't think it is worth it to use jQuery promise logic directly because these days you are likely to have industry standard logic elsewhere in your app and it's quite a pain to have two slightly different implementations in use. For simple things with jQuery ajax, I just stick with .then() on a jQuery promise. For more involved things with nested or chained promises, I cast to a standard promise with Promise.resolve() so then I know the exact behavior it will have in all circumstances and it will work like all the other promises in my code.

jfriend00
  • 683,504
  • 96
  • 985
  • 979