# what is the importance of zone.js in angular ?

774 views
0

0

zone.js is the secret sauce of angular which creates/monkey patches all async APIs and events that are triggered across the application. It creates an execution context which monitors which APIs are fired and what events are triggered.

For e.g. , In Angular, When we make a call to platformBrowserDynamic().bootstrapModule(AppModule) in our main.ts, module is instantiated. But before actual instantiation, an instance of NGZone is created.

In the constructor of NGZone, Zone.js is loaded which creates a root zone. Further, a new child zone named ‘angular’ is created by calling zone.fork method. Here, angular defines all the callbacks as part of zone specifications to which is subscribes all async tasks/APIs which are fired in angular application, whenever any async call happens.

In these callbacks, angular emits events. Angular also subscribes to these events and runs change detection logic by calling method tick(). change detection algorithm maintains a copy of execution context data all the time and when an event changes any data, it runs a DIFFing algorithm to identify what has changed since the last event was fired and changes only that part of the data object.

Now, the job of invoking callbacks specified in the zone specification lies on the Zone.js. To do this job, Zone.js monkey patches all the async APIs.

Monkey Patching:

Monkey patching is creating a wrapper on the primitive browser APIs, which is done to extend functionality of the built in APIs. Angular executes it’s own logic first in the monkey patched APIs before passing the control to the actual API call.

For e.g. for patching browser function like

window.setTimeOut(()=>console.log(‘async task’),0);

Angular, defines a patchTimer API in browser.ts. In this function, another method patchMethod() of utils.ts is called which is responsible for the actual monkey-patching of setTimeout() and clearTimeout().

Below is the code snippet from timer.js and utils.js for patchTimer() and patchMethod()

//timers.ts
//Some code
export function patchTimer(window: any, setName: string, cancelName: string, nameSuffix: string) {
//Some code
setNative =
patchMethod(window, setName, (delegate: Function) => function (self: any, args: any[]) {
//Some code
//Function definition to be executed when someone calls window.setTimeOut(fn,0);
scheduleMacroTaskWithCurrentZone(setName, args[0], options, scheduleTask, clearTask); // args[0] is the callback, options is of type TaskData which contains the time delay for calling callback.
//Some code
});
//Some code
}

//Utils.ts
//Some code
export function patchMethod(
target: any, name: string,
patchFn: (delegate: Function, delegateName: string, name: string) => (self: any, args: any[]) =>
any): Function {
//Some code
const patchDelegate = patchFn(delegate, delegateName, name);
proto[name] = function () {    //Here proto[name] is actual api like window.setTimeOut
return patchDelegate(this, arguments as any);
};
//Some code
}

As seen in the code above, the patchMethod() accepts the patchFn which is either setTimeout() or clearTimeout() and returns another function. This patchMethod() is the one which is actually called everytime when timer APIs are called.

The idea of monkey patching other APIs works exactly similar to what we just saw above.

Hope that answers the query !!