Nunca promises resolvidas causam memory leaks?

Eu tenho uma promise. Eu criei para cancelar um pedido AJAX se eu precisar. Mas como não preciso cancelar o AJAX, nunca o resolvi e o AJAX foi concluído com êxito.

Um sinete simplificado:

var defer = $q.defer(); $http({url: 'example.com/some/api', timeout: defer.promise}).success(function(data) { // do something }); // Never defer.resolve() because I don't need to cancel that ajax. What happens to this promise after request? 

Nunca promises resolvidas como essa causam vazamentos de memory? Você tem algum conselho sobre como gerenciar o ciclo de vida da promise?

Bem, estou supondo que você não mantenha uma referência explícita a ele, pois isso o forçaria a permanecer alocado.

O teste mais simples que eu pude pensar é realmente alocar muitas promises e não resolvê-las:

 var $q = angular.injector(["ng"]).get("$q"); setInterval(function () { for (var i = 0; i < 100; i++) { var $d = $q.defer(); $d.promise; } }, 10); 

E então assistindo a pilha em si. Como podemos ver nas ferramentas de criação de perfil do Chrome, isso acumula a memory necessária para alocar 100 promises e, em seguida, apenas "permanece lá" com menos de 15 megabytes para toda a página JSFIddle

insira a descrição da imagem aqui

Do outro lado, se olharmos para o código-fonte de $q

Podemos ver que não há referência de um ponto global a uma promise específica, mas apenas de uma promise aos seus retornos de chamada. O código é muito legível e claro. Vamos ver se você tem, no entanto, uma referência do retorno de chamada para a promise.

 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); 

insira a descrição da imagem aqui

Então, após a alocação inicial - parece que é capaz de lidar com isso também 🙂

Também podemos ver alguns padrões interessantes de GC se deixarmos o último exemplo dele funcionar por mais alguns minutos. Podemos ver que demora um pouco - mas é capaz de limpar os retornos de chamada.

insira a descrição da imagem aqui

Resumindo - pelo menos nos navegadores modernos - você não precisa se preocupar com promises não resolvidas, desde que você não tenha referências externas a elas.