Skip to content

Instantly share code, notes, and snippets.

@fearphage
Last active October 18, 2022 20:19
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fearphage/4341799 to your computer and use it in GitHub Desktop.
Save fearphage/4341799 to your computer and use it in GitHub Desktop.
$.whenAll jQuery extension

$.whenAll is an extension to jQuery's $.when. The main difference is $.when stops when it receives the first rejected promise. This extension treats all successes and failures as progress events. After all the promises have completed, the global promise is resolved if there were no errors. Otherwise the global promise is rejected.

Sameple #1

$.whenAll($.get('http://github.com'), $.get('good luck with this one'))
  .then(
    // success callback
    function(request) {}
    // failure callback - called once at the end
    ,function() {}
    // progress callback - called twice (before the failure callback)
    ,function(data, state, jqXhr) {
      // $.ajax().done/fail so the params are conditional based on a success or failure
      // The second param is consistently the state of the request.
      if (state == 'sucess') {
        // data is the data returned as expected
        // jqXhr is what you expect
      }
      else {
        // data is actually the jqXhr object for failed requests
        // jqXhr is the text of the error "Not Found" in this example
      }
    }
  )
;

Sample #2

var baseUrl = 'http://magic.value/here/'.
$.whenAll($('input.foo')
  .map(function() {
    return $.get(baseUrl + this.value);
  })
  .get()
)
  .progress(function() {
    // update visuals to show this failed
  })
  .failed(function() {
    // reset state to allow the user to resubmit
  })
;
;(function($) {
var slice = [].slice;
$.whenAll = function(array) {
var
resolveValues = arguments.length == 1 && $.isArray(array)
? array
: slice.call(arguments)
,length = resolveValues.length
,remaining = length
,deferred = $.Deferred()
,i = 0
,failed = 0
,rejectContexts = Array(length)
,rejectValues = Array(length)
,resolveContexts = Array(length)
,value
;
function updateFunc (index, contexts, values) {
return function() {
!(values === resolveValues) && failed++;
deferred.notifyWith(
contexts[index] = this
,values[index] = slice.call(arguments)
);
if (!(--remaining)) {
deferred[(!failed ? 'resolve' : 'reject') + 'With'](contexts, values);
}
};
}
for (; i < length; i++) {
if ((value = resolveValues[i]) && $.isFunction(value.promise)) {
value.promise()
.done(updateFunc(i, resolveContexts, resolveValues))
.fail(updateFunc(i, rejectContexts, rejectValues))
;
}
else {
deferred.notifyWith(this, value);
--remaining;
}
}
if (!remaining) {
deferred.resolveWith(resolveContexts, resolveValues);
}
return deferred.promise();
};
})(jQuery);
@nkskalyan
Copy link

You saved my day bro 😄

@fearphage
Copy link
Author

Outstanding. Glad I could help.

@ThumbSnail
Copy link

Awesome, solved my problem and worked great!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment