2017-03-24 11 views
11

में वर्तमान क्षेत्र के पथ को प्रिंट करने के लिए कैसे मैं ज़ोन (zone.js) के साथ प्रयोग कर रहा हूं और मुझे एहसास हुआ कि मुझे नहीं पता कि सभी जोनों को रूट से वर्तमान क्षेत्र में प्रिंट करने का सबसे अच्छा तरीका क्या है त्रुटि।जोन.जेएस

/.../zone-test/node_modules/zone.js/dist/zone-node.js:170 
         throw error; 
         ^
Error: it's broken 
    at new Error (native) 
    at failedFunc (/.../zone-test/zone_02.js:12:9) [zoneB] 
    at Timeout.setTimeout (/.../zone-test/zone_02.js:28:22) [zoneB] 
    at Zone.runTask (/.../zone-test/node_modules/zone.js/dist/zone-node.js:166:47) [<root> => zoneB] 
    at Timeout.ZoneTask.invoke (/.../zone-test/node_modules/zone.js/dist/zone-node.js:416:38) [<root>] 
    at Timeout.data.args.(anonymous function) [as _onTimeout] (/.../zone-test/node_modules/zone.js/dist/zone-node.js:1590:25) [<root>] 
    at ontimeout (timers.js:365:14) [<root>] 
    at tryOnTimeout (timers.js:237:5) [<root>] 
    at Timer.listOnTimeout (timers.js:207:5) [<root>] 
:

require('zone.js'); 

function failedFunc() { 
    throw new Error("it's broken"); 
} 

let rootZone = Zone.current; 

function func1() { 
    let zoneA = rootZone.fork({name: 'zoneA'}); 
    zoneA.run(() => { 
    setTimeout(() => func2()); 
    }); 
} 

function func2() { 
    let zoneB = Zone.current.fork({name: 'zoneB'}); 

    zoneB.run(() => { 
    setTimeout(() => failedFunc()); 
    }); 
} 

func1(); 

जब मैं इस उदाहरण चलाने यह निम्न उत्पादन देता है:

उदाहरण के लिए इस कोड को setTimeout() के साथ दो नेस्टेड कॉलबैक का उपयोग करता है और उसके बाद एक समारोह failedFunc() कहा जाता है कि एक त्रुटि फेंकता कॉल

त्रुटि को फेंकने वाले क्षेत्र के लिए सही पथ <root> =>zoneA =>zoneB है।

हालांकि यह आउटपुट से स्पष्ट नहीं है। केवल [root] और zoneB है और इसमें zoneA का उल्लेख नहीं है जो भ्रमित है। मुझे लगता है कि ऐसा इसलिए है क्योंकि zone.js का बंदर पैच केवल कॉल स्टैक में लाइनों में जोन जानकारी जोड़ता है। तो जब मैं zoneA बनाने से setTimeout() का उपयोग कर रहा हूं तो आउटपुट में किसी भी पंक्ति के अनुरूप नहीं है और इसलिए मैं इसे कहीं भी नहीं देख रहा हूं।

फिर भी, मैं अपने सभी माता-पिता को पुन: स्थापित करके वर्तमान क्षेत्र के पथ को प्रिंट कर सकता हूं लेकिन इसका मतलब है कि मुझे यह जानने की आवश्यकता है कि पहली बार त्रुटि कहाँ हुई और इसमें निम्न कोड जोड़ें (जो अभ्यास में बहुत कठिन होगा):

function failedFunc() { 
    let zone = Zone.current; 
    let zones = []; 
    while (zone) { 
    zones.push(zone.name); 
    zone = zone.parent; 
    } 
    console.log(zones); 

    throw new Error("it's broken"); 
} 

// ... 

अब मैं इस जब चलाने मैं मैं क्या जरूरत मिल जाएगा:

[ 'zoneB', 'zoneA', '<root>' ] 

/.../zone-test/node_modules/zone.js/dist/zone-node.js:170 
         throw error; 
         ^
Error: it's broken 
    at new Error (native) 

तो मैं कैसे व्यवहार में और एक तरह से zone.js उपयोग करने के लिए है कि यह इस की तुलना में आसान है सोच रहा हूँ।

+0

Zonejs ऐसे output.https पाने के लिए ZoneFrame की अवधारणा का उपयोग करता है: सवाल-जवाब पूरा स्टैकट्रेस मुद्रण के बारे में है //github.com/angular/zone.js/blob/ v0.8.5/lib/zone.ts # L1656-L1676। आप ग्लोबल का अपना संस्करण लिख सकते हैं। त्रुटि। जैसा कि मैंने देखा है कि यह आउटपुट अक्सर बदल जाता है। अंतिम प्रतिबद्धता की जांच करें https://github.com/angular/zone.js/commit/681a01788e2097b1d3751a07afae626deb427a60 – yurzui

+0

मुझे लगता है कि आप लंबे स्टैकट्रेसज़ोन की तलाश में हैं, मैंने आपके कोड को थोड़ा सा बदल दिया है और जेएसफ़ाइल: https://jsfiddle.net/Oski/ye0yz8c4/2/मुझे 'लांग-स्टैक-ट्रेस-जोन' नहीं मिला, इसलिए मैंने इसे HTML अनुभाग में चिपकाया। 'Zone.current' हमेशा उस क्षेत्र को वापस लौटाता है जिसमें इसे चलाया जा रहा है – Oskar

उत्तर

7

से भरा स्टैकट्रेस प्राप्त करने के लिए अपने zone आप, उपयोग करने के लिए long-stack-trace-zone

कृपया ध्यान दें कि मैं एक अपवाद फेंक रहा हूँ, यही कारण है कि तुम मेरे स्निपेट में एक त्रुटि देखेंगे।

function failedFunc() { 
 
    throw new Error("it's broken"); 
 
} 
 

 
function func1() { 
 
    let zoneA = Zone.current.fork({ 
 
    name: 'zoneA' 
 
    }); 
 
    zoneA.run(function() { 
 
    setTimeout(function() { 
 
     func2() 
 
    }); 
 
    }); 
 
} 
 

 
function func2() { 
 
    let zoneB = Zone.current.fork({ 
 
    name: 'zoneB' 
 
    }); 
 

 
    zoneB.run(function() { 
 
    setTimeout(function() { 
 
     failedFunc() 
 
    }); 
 
    }); 
 
} 
 

 
Zone.current.fork({ 
 
    onHandleError: function(parentZoneDelegate, currentZone, targetZone, error) { 
 
    console.log(error.stack); 
 
    } 
 
}).fork(Zone.longStackTraceZoneSpec).run(func1);
<script src="https://cdnjs.cloudflare.com/ajax/libs/zone.js/0.8.5/zone.min.js"></script> 
 
<!-- https://raw.githubusercontent.com/angular/zone.js/master/dist/long-stack-trace-zone.min.js --> 
 
<script> 
 
!function(t,a){"object"==typeof exports&&"undefined"!=typeof module?a():"function"==typeof define&&define.amd?define(a):a()}(this,function(){"use strict";function t(){return new Error(u)}function a(){try{throw t()}catch(a){return a}}function e(t){return t.stack?t.stack.split(i):[]}function n(t,a){for(var n=e(a),r=0;r<n.length;r++){var c=n[r];s.hasOwnProperty(c)||t.push(n[r])}}function r(t,a){var e=[a.trim()];if(t)for(var r=(new Date).getTime(),c=0;c<t.length;c++){var o=t[c],s=o.timestamp,f="____________________Elapsed "+(r-s.getTime())+" ms; At: "+s;f=f.replace(/[^\w\d]/g,"_"),e.push(h.replace(_,f)),n(e,o.error),r=s.getTime()}return e.join(i)}function c(t,a){a>0&&(t.push(e((new l).error)),c(t,a-1))}function o(){var t=[];c(t,2);for(var a=t[0],e=t[1],n=0;n<a.length;n++){var r=a[n];if(r.indexOf(u)==-1){var o=r.match(/^\s*at\s+/);if(o){h=o[0]+_+" (http://localhost)";break}}}for(var n=0;n<a.length;n++){var r=a[n],i=e[n];if(r!==i)break;s[r]=!0}}var i="\n",s={},f="__creationTrace__",u="STACKTRACE TRACKING",_="__SEP_TAG__",h=_+"@[native]",l=function(){function t(){this.error=g(),this.timestamp=new Date}return t}(),d=t(),k=a(),g=d.stack?t:k.stack?a:t;Zone.longStackTraceZoneSpec={name:"long-stack-trace",longStackTraceLimit:10,getLongStackTrace:function(t){if(t){var a=t[Zone.__symbol__("currentTask")],e=a&&a.data&&a.data[f];return e?r(e,t.stack):t.stack}},onScheduleTask:function(t,a,e,n){var r=Zone.currentTask,c=r&&r.data&&r.data[f]||[];return c=[new l].concat(c),c.length>this.longStackTraceLimit&&(c.length=this.longStackTraceLimit),n.data||(n.data={}),n.data[f]=c,t.scheduleTask(e,n)},onHandleError:function(t,a,e,n){var c=Zone.currentTask||n.task;if(n instanceof Error&&c){var o=r(c.data&&c.data[f],n.stack);try{n.stack=n.longStack=o}catch(i){}}return t.handleError(e,n)}},o()}); 
 
</script>