ฉันสมมติว่าคุณไม่ได้อ้างอิงอย่างชัดเจนเนื่องจากจะบังคับให้จัดสรรต่อไป
การทดสอบที่ง่ายที่สุดที่ฉันคิดได้คือการจัดสรรสัญญาจำนวนมากและไม่สามารถแก้ไขได้:
var $q = angular.injector(["ng"]).get("$q");
setInterval(function () {
for (var i = 0; i < 100; i++) {
var $d = $q.defer();
$d.promise;
}
}, 10);
แล้วดูกองเอง. ดังที่เราเห็นในเครื่องมือสร้างโปรไฟล์ Chrome สิ่งนี้จะสะสมหน่วยความจำที่จำเป็นเพื่อจัดสรรสัญญา 100 สัญญาจากนั้นก็ "อยู่ที่นั่น" ที่น้อยกว่า 15 เมกะไบต์สำหรับทั้งหน้า JSFIddle
จากอีกด้านหนึ่งถ้าเราดู$q
ซอร์สโค้ด
เราจะเห็นว่าไม่มีการอ้างอิงจากจุดทั่วโลกถึงคำสัญญาใด ๆ แต่มาจากคำสัญญาไปจนถึงการเรียกกลับเท่านั้น รหัสนี้อ่านได้และชัดเจนมาก มาดูกันว่าถ้าคุณมีข้อมูลอ้างอิงจากการโทรกลับไปยังคำสัญญา
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) {
$d.promise.then(function () {
console.log($d);
});
})($d);
}
}, 10);
หลังจากการจัดสรรครั้งแรกดูเหมือนว่าจะสามารถจัดการได้เช่นกัน :)
นอกจากนี้เรายังสามารถเห็นรูปแบบที่น่าสนใจของ GC หากเราปล่อยให้ตัวอย่างสุดท้ายของเขาทำงานต่อไปอีกสองสามนาที เราจะเห็นว่าต้องใช้เวลาสักครู่ แต่ก็สามารถล้างการโทรกลับได้
ในระยะสั้น - อย่างน้อยในเบราว์เซอร์สมัยใหม่ - คุณไม่ต้องกังวลกับคำสัญญาที่ยังไม่ได้รับการแก้ไขตราบเท่าที่คุณไม่มีการอ้างอิงจากภายนอกถึงพวกเขา