Saya punya Promise
. Saya membuatnya untuk membatalkan permintaan AJAX jika diperlukan. Tetapi karena saya tidak perlu membatalkan AJAX itu, saya tidak pernah menyelesaikannya dan AJAX berhasil diselesaikan.
Cuplikan yang disederhanakan:
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?
Apakah janji yang tidak pernah terwujud menyebabkan kebocoran memori? Apakah Anda punya saran tentang cara mengelola Promise
siklus hidup?
javascript
angularjs
memory-leaks
promise
angular-promise
Umut Benzer
sumber
sumber
Jawaban:
Nah, saya berasumsi Anda tidak menyimpan referensi eksplisit karena itu akan memaksanya untuk tetap dialokasikan.
Tes paling sederhana yang dapat saya pikirkan adalah mengalokasikan banyak janji dan tidak menyelesaikannya:
var $q = angular.injector(["ng"]).get("$q"); setInterval(function () { for (var i = 0; i < 100; i++) { var $d = $q.defer(); $d.promise; } }, 10);
Dan kemudian perhatikan heap itu sendiri. Seperti yang dapat kita lihat di alat profil Chrome, ini mengakumulasikan memori yang dibutuhkan untuk mengalokasikan 100 janji dan kemudian hanya "tetap di sana" kurang dari 15 megabyes untuk seluruh halaman JSFIddle
Dari sisi lain, jika kita melihat
$q
kode sumbernyaKita dapat melihat bahwa tidak ada referensi dari titik global ke suatu promise tertentu, melainkan hanya dari satu promise ke callback-nya. Kode tersebut sangat mudah dibaca dan jelas. Mari kita lihat bagaimana jika Anda memiliki referensi dari callback ke 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);
Jadi setelah alokasi awal - sepertinya itu bisa mengatasinya juga :)
Kita juga bisa melihat beberapa pola GC yang menarik jika kita membiarkan contoh terakhirnya berjalan beberapa menit lagi. Kami dapat melihat bahwa ini membutuhkan waktu - tetapi dapat membersihkan callback.
Singkatnya - setidaknya di browser modern - Anda tidak perlu khawatir tentang janji yang belum terselesaikan selama Anda tidak memiliki referensi eksternal ke sana
sumber
var b = $http.get(...)
atau tambahkan callback ke sana. Itu juga memiliki referensi untuk itu. Jika sesuatu menyelesaikannya (seperti yang Anda katakan - terlalu lama untuk diselesaikan berarti tekad) - itu harus memiliki referensi padanya. Jadi ya - ini tidak akan di-GC