Learn basic Zone.js by examples
@JiaLiPassion
Who am I
- Name: Jia Li
- Company: ThisDot
- Zone.js: Code Owner
- Angular: Collaborator
Agenda
- What's Zone.js
- When and why you need Zone.js
- Zone.js in Angular
What is Zone.js
A Zone is an execution context that persists across async tasks.
Created by Brian Ford inspired by Dart.
What zone.js can do
-
Provide execution context
-
Provide async task lifecycle hook
-
Provide error handler for async operations
Execution context in zone.js
zone.run(function() {
// function is in the zone
// just like `this`, we have a zoneThis === zone
expect(zoneThis).toBe(zone);
setTimeout(function() {
// the callback of async operation
// will also have a zoneThis === zone
// which is the zoneContext when this async operation
// is scheduled.
expect(zoneThis).toBe(zone);
});
Promise.resolve(1).then(function() {
// all async opreations will be in the same zone
// when they are scheduled.
expect(zoneThis).toBe(zone);
});
});
Async Error Handling
Zone.current.fork(
{
name: 'error',
onHandleError: (delegate, curr, target, error) => {
logger.error(error);
return delegate.handleError(target, error);
}
}).runGuarded(() => {
setTimeout(() => {
throw new Error('timeout error');
});
setTimeout(() => {
throw new Error('another timeout error');
});
});
When should we use Zone
- Test
- Sync(Disallow Async)
- Async(Auto done, Auto cleanup)
- FakeAsync()
- Debug
- LongStackTrace
- Task Tracing
- Performance measure
- Framework AutoRender
- User Action Tracing
- Resource Releasing
Demo: LongStackTrace
function main () {
b1.addEventListener('click', bindSecondButton);
}
/*
* What if your stack trace could tell you what
* order the user pushed the buttons from the stack trace?
* What if you could log this back to the server?
* Think of how much more productive your debugging could be!
*/
function bindSecondButton () {
b2.addEventListener('click', throwError);
}
function throwError () {
throw new Error('aw shucks');
}
main();
Demo: Tracking: Counting
function btnClicked () {
recurRandonGenerateTimeout(10);
}
function recurRandonGenerateTimeout (x) {
if (x > 0) {
setTimeout(function () {
for (var i = x; i < 8; i++) {
recur(x - 1, Math.random()*100);
}
}, t);
}
}
Performance Profiling
function btnClicked () {
asyncHeavyWork1();
asyncHeavyWork2();
asyncHttpRequest();
}
Auto releasing
const fs = require('fs');
fs.open('./test.txt', 'r', (err, fd) => {
if (err) throw err;
fs.fstat(fd, (err, stat) => {
if (err) throw err;
doSomething(fd, err => {});
doSomethingElse(fd, err => {});
});
});
const autoReleaseFSZone = Zone.current.fork({
name: 'releaseFS',
onHasTask: (pd, curr, target, hasTaskState) => {
if (!hasTaskState.macroTask && !hasTaskState.microTask && fd !== -1) {
fs.close(fd, (err) => {
if (err) throw err;
fd = -1;
});
}
return pd.hasTask(target, hasTaskState);
}
});
User Action Tracking
viewBtnClicked() {
httpRequest(viewUrl);
httpRequest(additionalInfoUrl);
}
orderBtnClicked() {
httpRequest(orderUrl);
httpRequest(transactionUrl);
}
errorBtnClicked() {
throw new Error();
}
UI Auto Rendering
function httpBtnClicked() {
httpRequestUrl(viewUrl);
}
function timeoutBtnClicked() {
setTimeout(() => {
data.timeout = 'timeout';
});
}
function addBtnClicked() {
if (!data.num) {
data.num = 0;
}
data.num ++;
}
Async Test
const api = require('./async-lib');
describe('testAsync', () => {
it('test async operation', (done) => {
let a = 0;
api.testAsync(a, r => {
expect(r).toBe(1);
done();
});
});
});
const api = require('./async-lib');
describe('testAsync', async(() => {
it('test async operation', () => {
let a = 0;
api.testAsync(a, r => {
expect(r).toBe(1);
});
});
}));
fakeAsync Test
describe('testAsync', () => {
it('test long async operation', (done) => {
setTimeout(() => {
// ... expect something.
done();
}, 10000);
});
});
describe('testAsync', () => {
it('test long async operation', fakeAsync(() => {
setTimeout(() => {
// ... expect something.
}, 10000);
tick(10000);
}));
});
Zone.js in Angular
NgZone
Tell when to trigger Change Detection
AsyncTest
FakeAsyncTest
SyncTest
Error Handling
Debug/Tracing
TaskTrackingZone
LongStackTraceZone
ngZone
ngZone.run(() => {
// will be in angular zone
// will trigger change detection
});
ngZone.runOutsideAngular(() => {
// will be outside angular zone
// will not trigger change detection
});
Thank you!
Learn zone.js by examples_shortver
By jiali
Learn zone.js by examples_shortver
- 775