{{title}} {{diff | date:'ss.sss'}}s / {{totalDiff | date:'mm:ss'}}

Thread Local Storage Execution Contexts for JavaScript with Zone

by Jeremy Likness

Principal Consultant

Why Zone?

JavaScript uses an event loop. Scripts are mostly asynchronous. This means you lose context when you:

  • Run code on a timer
  • Run code that is triggered by a DOM event
  • Run code to process data that was fetched asnychronously

JavaScript Event Queue

JavaScript Event Queue
Timer Event Queue
Keyboard Input Event Queue
Button Click Event Queue

 

Every task has it's own "context" unless you want to clobber globals

No Zone Implementation


console.log('start');
console.log('enqueue');
setTimeout(function () {
   console.log('task');
   console.log('dequeue');
}, 100);
console.log('end');
                    

Zone Implementation



Zone.run(function () {
   console.log('start');
   setTimeout(function() {
      console.log('task');
   }, 100);
   console.log('end');
});
                    

Demo: How Does It Work?

Launch jsFiddle

... a zone that traps errors

... a zone that times tasks

Zone Walkthrough: Fork and Run

zone.fork({
  beforeTask: function () {
    console.log('hi');
  }
}).run(function () {
  // do stuff
});

                    
  • Fork creates child zone (inherits parent) and defines behavior
  • Run to execute code within the zone

Zone Walkthrough: 'Turns'

function myZone() {
    var _alert = window.alert,
        _alertConsole = function (msg) { console.log(msg); };
    return {
        beforeTask: function () { window.alert = _alertConsole; },
        afterTask: function () { window.alert = _alert; }
    };
}
                    
  • beforeTask — set-up
  • afterTask — tear down

Zone Walkthrough: 'Turns' Continued

  • enqueueTask — A function is registered for a turn
  • dequeueTask — A function ends (therefore ending the turn)

Zone Walkthrough: Inheritance

function myZone() {
   return {
      $afterTask: function (parent) {
         return function () { /* do stuff before */
            parent(); /* do stuff after */ }; },
      '+afterTask': function () { /* runs after parent */ },
      '-afterTask': function () { /* runs before parent */ },
   };
}
                    

Zone Walkthrough: API

  • onZoneCreated — Zone is forked (uber-setup)
  • onError — Error thrown within the zone

Zone Walkthrough: Hooks

setTimeout

setInterval

alert

prompt

addEventListener

Demo: Zone with Angular

Bootstrapping Angular

Stacktrace Zone

My Custom Zone

Thread Local Storage Execution Contexts for JavaScript with Zone

by Jeremy Likness

Principal Consultant
Window size: 1920 x 1080
Viewport size: 1920 x 976