3

It seems that there is no way for jQuery to know when your app is done using a promise. Since memory is managed in js, I presume that the promise continues to exist until all references to it are gone. Specifically, it will exist indefinitely until it is resolved AND the code that created or used it has finished exiting (functions returned etc). At which point it will be garbaged collected.

Can anyone verify my assumptions? Or add other thoughts to this?

Understanding the underlying mechanics has some important connotations; memory leaks, potential caching opportunities (via persisting promises after they have been resolved), etc. My next step is to dive into the jQuery source, but I was hoping for some additional guidance before starting that.

jtfairbank
  • 2,311
  • 2
  • 21
  • 33
  • Your assumptions look pretty accurate. I'm not entirely sure about the unresolved promise object, i guess that will depend on if anything is still referencing the deferred object that it came from. – Kevin B Apr 09 '14 at 19:30
  • I would assume there is some sort of list of callback functions jQuery manages internally that react to a promise being done. I would also highly doubt that this list is time sensitive. – Travis J Apr 09 '14 at 19:32

2 Answers2

2

If there are no references to a resolved promise, it will (eventually) be disposed. Otherwise, it will be kept in memory in case anyone wants to access its value.

Promises are no different here from any other object in this case.

Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
  • Related http://stackoverflow.com/questions/20068467/angular-js-do-never-resolved-promises-cause-memory-leak/20068922#20068922 – Benjamin Gruenbaum Apr 09 '14 at 19:36
  • If you'd like me to elaborate I don't mind doing so. I ran the profiler to be sure and it's very similar to my $q answer on a similar question (the comment above this one). It's worth mentioning jQuery's promises are problematic for a lot of other reasons. – Benjamin Gruenbaum Apr 09 '14 at 19:53
0

Promises are only removed in one case, if the progress is done.

js source

.done( updateFunc( i, resolveContexts, resolveValues ) )
...->
deferred.resolveWith( contexts, values );

To note, resolveWith is part of jQuery convention to use what they call a tuple, resolve in this case, suffixed with "With" in order to essentially issue a callback to deferred.resolve. This essentially calls the original callback using the same context as the deferred object.

Internally when a callback from a list is fired, jQuery will remove that from the list of callbacks held for that list.

Thus, the only way a promise is resolved, is by being done. There is no timing which monitors it.

The promise will either be attached to the target if one is passed in the jQuery constructor, or will be attached to a new instance of jQuery. This will be the lifetime of the list which holds these deferred callback lists.

As with any other garbage collection, this lifetime will be browser dependent (IE sometimes does interesting things).

Travis J
  • 81,153
  • 41
  • 202
  • 273