Should I always reference the JQuery Deferred.resolve or Deferred.reject?
So, as shown below, it only deals with the ajax call success case, if the ajax call fails, it is ignored and the deferred.reject () function will never be called. So, if we run into a bad case, will the event listener inside jQuery continue to leak memory forever?
$.when(loadSomething).done(function() {
// ...
});
function loadSomething() {
var deferred = $.Deferred();
// Only deal with the success case,
// If the ajax call failed, it is ignored and the deferred.reject() will never be invoked.
// So if we meet the failed case, will there any event listener inside jQuery will be keeped
// forever?
ajaxCallToLoad(onResult);
function onResult() {
deferred.resolve();
}
return deferred.promise();
}
source to share
So, if we encounter a bad case, will the event listener inside jQuery lose the memory leak forever?
Almost certainly not.
But if you do, you are explicitly using promise semantics, but then breaking the promise contract. This is bad practice. You should use the "best practices":
-
Keep using promises, but stick to the contract. Update
ajaxCallToLoad
so that it will notify you of the error as well, and callreject
on your pending one when it does. (IfajaxCallToLoad
using a jQuery function$.ajax
, you can just use the objectjqXHR
that returns$.ajax
, it implementsPromise
.) -
If you don't want to honor the contract of promise, just use a regular "success" callback, not a promise.
source to share
To answer your real question, you will only leak memory if you maintain a reference to deferred and / or promise somewhere in your code, regardless of whether you allow or deny deferred. If there are no references then it will be garbage collected as usual.
However, I think that in this case, instead of manually creating the Deferred, you should use a method .then
that allows you to transform / filter the results. For the sake of this example, let's create a method called load
that just randomly allows or rejects a pending ajax request that could potentially fail.
function load() {
return $.Deferred(function( dfr ) {
if ( Date.now() % 2 ) {
dfr.resolve( 1 );
}
else {
dfr.reject( "OHNO!" );
}
}).promise();
}
You can now use. then filter it like this:
var filteredResult = load().then(function( result ) {
return result * 2;
});
filteredResult
is now a promise when it doubles the original result when resolving the load, so it filterResult.done( console.log.bind( console ) )
prints 2
to the console. If the download is unsuccessful / rejected, the opt-out handlers will work as expected.
source to share