
committed by
Kara Erickson

parent
7b3bcc23af
commit
5eb7426216
59
packages/zone.js/example/basic.html
Normal file
59
packages/zone.js/example/basic.html
Normal file
@ -0,0 +1,59 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Zone.js Basic Demo</title>
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
<script src="../dist/zone.js"></script>
|
||||
<script src="../dist/long-stack-trace-zone.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>Basic Example</h1>
|
||||
|
||||
<button id="b1">Bind Error</button>
|
||||
<button id="b2">Cause Error</button>
|
||||
|
||||
<script>
|
||||
|
||||
/*
|
||||
* This is a simple example of async stack traces with zones
|
||||
*/
|
||||
|
||||
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');
|
||||
}
|
||||
|
||||
/*
|
||||
* Bootstrap the app
|
||||
*/
|
||||
//main();
|
||||
Zone.current.fork(
|
||||
{
|
||||
onHandleError: function (parentZoneDelegate, currentZone, targetZone, error) {
|
||||
console.log(error.stack);
|
||||
}
|
||||
}
|
||||
).fork(Zone.longStackTraceZoneSpec).run(main);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
65
packages/zone.js/example/benchmarks/addEventListener.html
Normal file
65
packages/zone.js/example/benchmarks/addEventListener.html
Normal file
@ -0,0 +1,65 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Zone.js addEventListenerBenchmark</title>
|
||||
<link rel="stylesheet" href="../css/style.css">
|
||||
<script src="../../dist/zone.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>addEventListener Benchmark</h1>
|
||||
|
||||
<h2>No Zone</h2>
|
||||
<button id="b1">Add/Remove same callback</button>
|
||||
<button id="b2">Add/Remove different callback</button>
|
||||
|
||||
<h2>With Zone</h2>
|
||||
<button id="b3">Add/Remove same callback</button>
|
||||
<button id="b4">Add/Remove different callback</button>
|
||||
|
||||
<div id="rootDiv"></div>
|
||||
|
||||
<script>
|
||||
b1.addEventListener('click', function () { addRemoveCallback(true, false); });
|
||||
b2.addEventListener('click', function () { addRemoveCallback(false, false); });
|
||||
b3.addEventListener('click', function () { addRemoveCallback(true, true); });
|
||||
b4.addEventListener('click', function () { addRemoveCallback(false, true); });
|
||||
var divs = [];
|
||||
var callbacks = [];
|
||||
var size = 100000;
|
||||
for(var i = 0; i < size; i++) {
|
||||
var div = document.createElement("div");
|
||||
var callback = (function(i) { return function() { console.log(i); }; })(i);
|
||||
rootDiv.appendChild(div);
|
||||
divs[i] = div;
|
||||
callbacks[i] = callback;
|
||||
}
|
||||
|
||||
function addRemoveCallback(reuse, useZone) {
|
||||
var start = performance.now();
|
||||
var callback = callbacks[0];
|
||||
for(var i = 0; i < size; i++) {
|
||||
var div = divs[i];
|
||||
if (!reuse) callback = callbacks[i];
|
||||
if (useZone)
|
||||
div.addEventListener('click', callback);
|
||||
else
|
||||
div.__zone_symbol__addEventListener('click', callback);
|
||||
}
|
||||
|
||||
for(var i = 0; i < size; i++) {
|
||||
var div = divs[i];
|
||||
if (!reuse) callback = callbacks[i];
|
||||
if (useZone)
|
||||
div.removeEventListener('click', callback);
|
||||
else
|
||||
div.__zone_symbol__removeEventListener('click', callback);
|
||||
}
|
||||
var end = performance.now();
|
||||
console.log(useZone ? 'use zone': 'native', reuse ? 'reuse' : 'new', end - start, 'ms');
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
50
packages/zone.js/example/benchmarks/event_emitter.js
Normal file
50
packages/zone.js/example/benchmarks/event_emitter.js
Normal file
@ -0,0 +1,50 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
const events = require('events');
|
||||
const EventEmitter = events.EventEmitter;
|
||||
require('../../dist/zone-node');
|
||||
|
||||
const emitters = [];
|
||||
const callbacks = [];
|
||||
const size = 100000;
|
||||
for (let i = 0; i < size; i++) {
|
||||
const emitter = new EventEmitter();
|
||||
const callback = (function(i) { return function() { console.log(i); }; })(i);
|
||||
emitters[i] = emitter;
|
||||
callbacks[i] = callback;
|
||||
}
|
||||
|
||||
function addRemoveCallback(reuse, useZone) {
|
||||
const start = new Date();
|
||||
let callback = callbacks[0];
|
||||
for (let i = 0; i < size; i++) {
|
||||
const emitter = emitters[i];
|
||||
if (!reuse) callback = callbacks[i];
|
||||
if (useZone)
|
||||
emitter.on('msg', callback);
|
||||
else
|
||||
emitter.__zone_symbol__addListener('msg', callback);
|
||||
}
|
||||
|
||||
for (let i = 0; i < size; i++) {
|
||||
const emitter = emitters[i];
|
||||
if (!reuse) callback = callbacks[i];
|
||||
if (useZone)
|
||||
emitter.removeListener('msg', callback);
|
||||
else
|
||||
emitter.__zone_symbol__removeListener('msg', callback);
|
||||
}
|
||||
const end = new Date();
|
||||
console.log(useZone ? 'use zone' : 'native', reuse ? 'reuse' : 'new');
|
||||
console.log('Execution time: %dms', end - start);
|
||||
}
|
||||
|
||||
addRemoveCallback(false, false);
|
||||
addRemoveCallback(false, true);
|
||||
addRemoveCallback(true, false);
|
||||
addRemoveCallback(true, true);
|
95
packages/zone.js/example/counting.html
Normal file
95
packages/zone.js/example/counting.html
Normal file
@ -0,0 +1,95 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Counting Pending Tasks</title>
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
<script src="../dist/zone.js"></script>
|
||||
<script src="js/counting-zone.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>Counting Pending Tasks</h1>
|
||||
|
||||
<p>We want to know about just the events from a single mouse click
|
||||
while a bunch of other stuff is happening on the page</p>
|
||||
|
||||
<p>This is useful in E2E testing. Because you know when there are
|
||||
no async tasks, you avoid adding timeouts that wait for tasks that
|
||||
run for an indeterminable amount of time.</p>
|
||||
|
||||
<button id="b1">Start</button>
|
||||
|
||||
<p id="output"></p>
|
||||
|
||||
<script>
|
||||
/*
|
||||
* Zone that counts pending async tasks
|
||||
*/
|
||||
const outputElem = document.getElementById('output');
|
||||
const countingZoneSpec = Zone['countingZoneSpec'];
|
||||
const myCountingZone = Zone.current.fork(countingZoneSpec).fork({
|
||||
onScheduleTask(parent, current, target, task) {
|
||||
parent.scheduleTask(target, task);
|
||||
console.log('Scheduled ' + task.source + ' => ' + task.data.handleId);
|
||||
outputElem.innerText = countingZoneSpec.counter();
|
||||
},
|
||||
onInvokeTask(parent, current, target, task) {
|
||||
console.log('Invoking ' + task.source + ' => ' + task.data.handleId);
|
||||
parent.invokeTask(target, task);
|
||||
outputElem.innerText = countingZoneSpec.counter();
|
||||
},
|
||||
onHasTask(parent, current, target, hasTask) {
|
||||
if (hasTask.macroTask) {
|
||||
console.log("There are outstanding MacroTasks.");
|
||||
} else {
|
||||
console.log("All MacroTasks have been completed.");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
* We want to profile just the actions that are a result of this button, so with
|
||||
* a single line of code, we can run `main` in the countingZone
|
||||
*/
|
||||
|
||||
b1.addEventListener('click', function () {
|
||||
myCountingZone.run(main);
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
* Spawns a bunch of setTimeouts which in turn spawn more setTimeouts!
|
||||
* This is a boring way to simulate HTTP requests and other async actions.
|
||||
*/
|
||||
|
||||
function main () {
|
||||
for (var i = 0; i < 10; i++) {
|
||||
recur(i, 800);
|
||||
}
|
||||
}
|
||||
|
||||
function recur (x, t) {
|
||||
if (x > 0) {
|
||||
setTimeout(function () {
|
||||
for (var i = x; i < 8; i++) {
|
||||
recur(x - 1, Math.random()*t);
|
||||
}
|
||||
}, t);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* There may be other async actions going on in the background.
|
||||
* Because this is not in the zone, our profiling ignores it.
|
||||
* Nice.
|
||||
*/
|
||||
function noop () {
|
||||
setTimeout(noop, 10*Math.random());
|
||||
}
|
||||
noop();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
8
packages/zone.js/example/css/style.css
Normal file
8
packages/zone.js/example/css/style.css
Normal file
@ -0,0 +1,8 @@
|
||||
body {
|
||||
padding: 50px;
|
||||
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #00B7FF;
|
||||
}
|
21
packages/zone.js/example/index.html
Normal file
21
packages/zone.js/example/index.html
Normal file
@ -0,0 +1,21 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Zone.js Examples</title>
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>Examples</h1>
|
||||
|
||||
<ol>
|
||||
<li><a href="basic.html">Tracing user actions with long stack traces</a></li>
|
||||
<li><a href="counting.html">Counting Tasks</a></li>
|
||||
<li><a href="profiling.html">Profiling Across Tasks</a></li>
|
||||
<li><a href="throttle.html">Throttle</a></li>
|
||||
<li><a href="web-socket.html">WebSocket</a></li>
|
||||
</ol>
|
||||
|
||||
</body>
|
||||
</html>
|
33
packages/zone.js/example/js/counting-zone.js
Normal file
33
packages/zone.js/example/js/counting-zone.js
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* See example/counting.html
|
||||
*/
|
||||
|
||||
Zone['countingZoneSpec'] = {
|
||||
name: 'counterZone',
|
||||
// setTimeout
|
||||
onScheduleTask: function(delegate, current, target, task) {
|
||||
this.data.count += 1;
|
||||
delegate.scheduleTask(target, task);
|
||||
},
|
||||
|
||||
// fires when...
|
||||
// - clearTimeout
|
||||
// - setTimeout finishes
|
||||
onInvokeTask: function(delegate, current, target, task, applyThis, applyArgs) {
|
||||
delegate.invokeTask(target, task, applyThis, applyArgs);
|
||||
this.data.count -= 1;
|
||||
},
|
||||
|
||||
onHasTask: function(delegate, current, target, hasTask) {
|
||||
if (this.data.count === 0 && !this.data.flushed) {
|
||||
this.data.flushed = true;
|
||||
target.run(this.onFlush);
|
||||
}
|
||||
},
|
||||
|
||||
counter: function() { return this.data.count; },
|
||||
|
||||
data: {count: 0, flushed: false},
|
||||
|
||||
onFlush: function() {}
|
||||
};
|
126
packages/zone.js/example/profiling.html
Normal file
126
packages/zone.js/example/profiling.html
Normal file
@ -0,0 +1,126 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Zones Profiling</title>
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
<script>
|
||||
__Zone_disable_Error = true;
|
||||
__Zone_disable_on_property = true;
|
||||
__Zone_disable_geolocation = true;
|
||||
__Zone_disable_toString = true;
|
||||
__Zone_disable_blocking = true;
|
||||
__Zone_disable_PromiseRejectionEvent = true;
|
||||
</script>
|
||||
<script src="../dist/zone.js"></script>
|
||||
<script src="../dist/long-stack-trace-zone.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>Profiling with Zones</h1>
|
||||
|
||||
<button id="b1">Start Profiling</button>
|
||||
|
||||
<script>
|
||||
/*
|
||||
* Let's say we want to know the CPU cost from some action
|
||||
* that includes async tasks. We can do this with zones!
|
||||
*/
|
||||
|
||||
/*
|
||||
* For this demo, we're going to sort an array using an async
|
||||
* algorithm when a button is pressed.
|
||||
*/
|
||||
function sortAndPrintArray (unsortedArray) {
|
||||
profilingZoneSpec.reset();
|
||||
asyncBogosort(unsortedArray, function (sortedArray) {
|
||||
console.log(sortedArray);
|
||||
console.log('sorting took ' + profilingZoneSpec.time() + ' of CPU time');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This is a really efficient algorithm.
|
||||
*
|
||||
* First, check if the array is sorted.
|
||||
* - If it is, call the wrapCallback
|
||||
* - If it isn't, randomize the array and recur
|
||||
*
|
||||
* This implementation is async because JavaScript
|
||||
*/
|
||||
function asyncBogosort (arr, cb) {
|
||||
setTimeout(function () {
|
||||
if (isSorted(arr)) {
|
||||
cb(arr);
|
||||
} else {
|
||||
var newArr = arr.slice(0);
|
||||
newArr.sort(function () {
|
||||
return Math.random() - 0.5;
|
||||
});
|
||||
asyncBogosort(newArr, cb);
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
||||
function isSorted (things) {
|
||||
for (var i = 1; i < things.length; i += 1) {
|
||||
if (things[i] < things[i - 1]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Bind button
|
||||
*/
|
||||
function main () {
|
||||
var unsortedArray = [3,4,1,2,7];
|
||||
b1.addEventListener('click', function () {
|
||||
sortAndPrintArray(unsortedArray);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This zone starts a timer at the start of each taskEnv,
|
||||
* and stops it at the end. It accumulates the total run
|
||||
* time internally, exposing it via `zone.time()`
|
||||
*
|
||||
* Note that this is the time the CPU is spending doing
|
||||
* bogosort, as opposed to the time from the start
|
||||
* of the algorithm until it's completion.
|
||||
*/
|
||||
var profilingZoneSpec = (function () {
|
||||
var time = 0,
|
||||
// use the high-res timer if available
|
||||
timer = performance ?
|
||||
performance.now.bind(performance) :
|
||||
Date.now.bind(Date);
|
||||
return {
|
||||
onInvokeTask: function (delegate, current, target, task, applyThis, applyArgs) {
|
||||
this.start = timer();
|
||||
delegate.invokeTask(target, task, applyThis, applyArgs);
|
||||
time += timer() - this.start;
|
||||
},
|
||||
time: function () {
|
||||
return Math.floor(time*100) / 100 + 'ms';
|
||||
},
|
||||
reset: function () {
|
||||
time = 0;
|
||||
}
|
||||
};
|
||||
}());
|
||||
|
||||
|
||||
/*
|
||||
* Bootstrap the app
|
||||
*/
|
||||
Zone.current.fork(profilingZoneSpec).run(main);
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
91
packages/zone.js/example/throttle.html
Normal file
91
packages/zone.js/example/throttle.html
Normal file
@ -0,0 +1,91 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Zones throttle</title>
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
<script src="../dist/zone.js"></script>
|
||||
<script src="../dist/long-stack-trace-zone.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Throttle Example</h1>
|
||||
|
||||
<button id="b2">Error</button>
|
||||
|
||||
<script>
|
||||
/*
|
||||
* In this example, we have a button that makes some request
|
||||
* to our server. We want to only make the request once per
|
||||
* 1s, so we use a `throttle` helper. If the request fails,
|
||||
* it's difficult to see where the failure originated from.
|
||||
*
|
||||
* Thankfully, we can use zones to preserve the stack even
|
||||
* across async tasks to get a better picture of the control
|
||||
* flow of the app.
|
||||
*/
|
||||
|
||||
var throttleMakeRequest;
|
||||
|
||||
/*
|
||||
* Start the app
|
||||
* Bind listeners
|
||||
*/
|
||||
function bootstrap () {
|
||||
b2.addEventListener('click', throttleMakeRequest);
|
||||
}
|
||||
|
||||
/*
|
||||
* Makes a request to the server
|
||||
* Will only make the request once every 1000ms
|
||||
*/
|
||||
throttleMakeRequest = throttle(function () {
|
||||
makeRequestToServer(handleServerResponse);
|
||||
}, 1000);
|
||||
|
||||
|
||||
/*
|
||||
* Pretend this makes a request to a server
|
||||
*/
|
||||
function makeRequestToServer (cb) {
|
||||
setTimeout(cb, 100);
|
||||
}
|
||||
|
||||
|
||||
function handleServerResponse (err, data) {
|
||||
throw new Error('Oops');
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns a fn that can only be called once
|
||||
* per `time` milliseconds
|
||||
*/
|
||||
function throttle (fn, time) {
|
||||
var id = null;
|
||||
if (typeof time !== 'number') {
|
||||
time = 0;
|
||||
}
|
||||
return function () {
|
||||
if (!id) {
|
||||
id = setTimeout(function () {
|
||||
id = null;
|
||||
fn();
|
||||
}, time);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Start the application
|
||||
*
|
||||
* If we start the application with `zone.run`, we
|
||||
* get long stack traces in the console!
|
||||
*/
|
||||
|
||||
//bootstrap();
|
||||
Zone.current.fork(Zone.longStackTraceZoneSpec).run(bootstrap);
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
38
packages/zone.js/example/web-socket.html
Normal file
38
packages/zone.js/example/web-socket.html
Normal file
@ -0,0 +1,38 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebSockets with Zones</title>
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
<script src="../dist/zone.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>
|
||||
Ensure that you started <code>node test/ws-server.js</code> before loading
|
||||
this page. Then check console output.
|
||||
</p>
|
||||
|
||||
<script>
|
||||
|
||||
var ws = new WebSocket('ws://localhost:8001');
|
||||
|
||||
ws.onopen = function() {
|
||||
Zone.current.fork({properties: {secretPayload: 'bah!'}, name: 'secrete-zone'}).run(function() {
|
||||
ws.onmessage = function(eventListener) {
|
||||
if (Zone.current.get('secretPayload') === 'bah!') {
|
||||
console.log("The current zone (id: %s) has secretPayload. Zones are working!",
|
||||
Zone.current.name);
|
||||
} else {
|
||||
console.error('Secret payload not found where expected! Zones are not working! :-(', Zone.current.name);
|
||||
}
|
||||
};
|
||||
console.log('Setting secret payload in the current zone (id: %s)', Zone.current.name);
|
||||
});
|
||||
|
||||
ws.send('hello!');
|
||||
};
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user