2014-11-22 12 views
6

Suche Hilfe von Nodejs Gurus da draußen auf die Verwendung von Versprechen. Ich habe das folgende Testprogramm, in dem ich eine asynchrone "q" -Funktion aufrufen, die einfach eine Ausnahme auslöst. Dieses Programm verliert Speicher ziemlich konsequent; aber das Leck verschwindet, wenn der Aufruf von .done() auskommentiert wird.Nodejs - Versprechen, unbehandelt Kündigung und Speicherleck

Warum tritt das Leck auf, wenn das Versprechen nicht abgeschlossen ist (d. H. No done() - Aufruf)? Ich habe versucht, dem documentation zu folgen, aber habe Schwierigkeiten, die Erklärung der Methode done() zu verstehen. Vielen Dank im Voraus für Ihre Hilfe!

Hier ist mein Code:

(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

Wie haben Sie festgestellt, dass ein Speicherleck auftritt? Auch nur neugierig, irgendeinen Grund, warum Sie diese ganze Sache in einer anonymen Funktion verpacken? –

+0

@torazaburo - der console.log-Aufruf, der Speicherauslastungsberichte eine ziemlich konstante Speicherbelegung mit .done() -Aufruf ausgibt, aber stetig wächst, wenn ich .done() auskommentiere. Anon-Funktion - dies wird vom Kaffee-Skript-Compiler generiert, der diesen Code-Stil erzeugt, um Variablen richtig zu erfassen, vor globalen Namenskonflikten etc. zu schützen. – PKK

+0

@torazaburo - Das sollte kein Problem sein, da die Testfunktion über setImmediate() ausgeführt wird. Anruf. – PKK

Antwort

5

meine eigene Frage zu beantworten, wird es hoffentlich jemand helfen.

Wenn man ein bisschen in den Bibliothekscode q eingräbt, sieht es so aus, als ob alle unbehandelten Ausnahmen standardmäßig in einem Array namens unhandledRejections abgelegt werden. Nicht sicher, warum es so implementiert wurde, aber vermutlich, um Entwicklern zu helfen, nicht behandelte Ausnahmen aufzuspüren. Dieses Verhalten kann durch Aufrufen von Q.stopUnhandledRejectionTracking() geändert werden. Als ich das tat, ging das Speicherleck weg, auch ohne den Anruf .done().

+1

Das Array 'unhandledRejections' scheint zu Unit-Testzwecken zu gehören: https://github.com/kriskowal/q/issues/265 – PKK

Verwandte Themen