2014-11-22 17 views
6

tìm kiếm sự trợ giúp từ các nút của nhóm chuyên gia về việc sử dụng lời hứa. Tôi có chương trình thử nghiệm sau đây, trong đó tôi gọi một hàm "q" không đồng bộ chỉ đơn giản là ném một ngoại lệ. Chương trình này rò rỉ bộ nhớ khá nhất quán; nhưng rò rỉ sẽ biến mất nếu bỏ ghi chú cuộc gọi .done().Nodejs - hứa hẹn, hủy kết thúc và rò rỉ bộ nhớ

Tại sao sự cố rò rỉ xảy ra khi lời hứa không được thực hiện (tức là không thực hiện được cuộc gọi)? Tôi đã cố gắng theo dõi documentation, nhưng gặp khó khăn khi hiểu được lời giải thích của phương thức done(). Cảm ơn trước sự giúp đỡ của bạn!

Dưới đây là mã của tôi:

(function() { 
    var MAX_ITER_COUNT, Q, iterCount, maxMem, noop, qDoit, test; 

    Q = require("q"); 

    iterCount = 0; 

    MAX_ITER_COUNT = 10 * 1000; 

    maxMem = 0; 

    noop = function() {}; 

    qDoit = function() { 
    var currentMem; 
    currentMem = Math.round(process.memoryUsage().heapUsed/1024/1024); 
    if (currentMem > maxMem) { 
     maxMem = currentMem; 
    } 
    console.log("" + iterCount + " - memory is: " + currentMem + "/" + maxMem + " MB"); 
    return Q(10).then(function() { 
     throw new Error("X"); 
    }); 
    }; 

    test = function() { 
    if (iterCount++ > MAX_ITER_COUNT) { 
     console.log("DONE"); 
     return; 
    } 

    // ---- If I uncomment the done() call below the leak goes away ---- 
    return qDoit()["finally"](function() { 
     return setImmediate(test); 
    }) 
    //.done(noop, noop, noop); 


    }; 

    Q.onerror = function() {}; 

    test(); 

}).call(this); 
+0

Làm cách nào bạn xác định rằng rò rỉ bộ nhớ đang xảy ra? Ngoài ra chỉ tò mò, bất kỳ lý do bạn đang gói toàn bộ điều này trong một chức năng vô danh? –

+0

@torazaburo - cuộc gọi console.log in các báo cáo sử dụng bộ nhớ sử dụng mem khá liên tục với lệnh .done(), nhưng tăng dần khi tôi nhận xét .done(). Hàm Anon - được tạo ra bởi trình biên dịch kịch bản lệnh cà phê, tạo ra kiểu mã này cho các biến phạm vi đúng cách, bảo vệ khỏi xung đột tên toàn cầu, v.v. – PKK

+0

@torazaburo - Đó không phải là vấn đề vì hàm kiểm tra được thực thi thông qua setImmediate() gọi điện. – PKK

Trả lời

5

Trả lời câu hỏi của riêng tôi, hy vọng nó sẽ giúp một ai đó.

Khi đào một chút vào mã thư viện q, có vẻ như tất cả ngoại lệ chưa được xử lý được đặt trong một mảng được gọi là unhandledRejections theo mặc định. Bạn không chắc chắn lý do tại sao nó được thực hiện như thế này, nhưng có lẽ để giúp các nhà phát triển theo dõi các ngoại lệ chưa được xử lý. Bạn có thể thay đổi hành vi này bằng cách gọi Q.stopUnhandledRejectionTracking(). Khi tôi làm điều này, rò rỉ bộ nhớ biến mất, ngay cả khi không có cuộc gọi .done().

+1

Mảng 'unhandledRejections' dường như dành cho mục đích thử nghiệm đơn vị: https://github.com/kriskowal/q/issues/265 – PKK