Bueno, supongo que no mantiene una referencia explícita a él, ya que eso lo obligaría a permanecer asignado.
La prueba más simple que se me ocurre es asignar muchas promesas y no resolverlas:
var $q = angular.injector(["ng"]).get("$q");
setInterval(function () {
for (var i = 0; i < 100; i++) {
var $d = $q.defer();
$d.promise;
}
}, 10);
Y luego mirando el montón en sí. Como podemos ver en las herramientas de creación de perfiles de Chrome, esto acumula la memoria necesaria para asignar 100 promesas y luego simplemente "permanece allí" a menos de 15 megabyes para toda la página JSFIddle.
Desde el otro lado, si miramos el $q
código fuente
Podemos ver que no hay referencia desde un punto global a ninguna promesa en particular, sino solo de una promesa a sus devoluciones de llamada. El código es muy legible y claro. Veamos qué sucede si, sin embargo, tiene una referencia de la devolución de llamada a la promesa.
var $q = angular.injector(["ng"]).get("$q");
console.log($q);
setInterval(function () {
for (var i = 0; i < 10; i++) {
var $d = $q.defer();
(function ($d) { // loop closure thing
$d.promise.then(function () {
console.log($d);
});
})($d);
}
}, 10);
Entonces, después de la asignación inicial, parece que también puede manejar eso :)
También podemos ver algunos patrones interesantes de GC si dejamos que su último ejemplo se ejecute durante unos minutos más. Podemos ver que lleva un tiempo, pero es capaz de limpiar las devoluciones de llamada.
En resumen, al menos en los navegadores modernos, no tiene que preocuparse por las promesas no resueltas siempre que no tenga referencias externas a ellas.