Skip to content

Commit 442283c

Browse files
committed
Add abort-timer demo.
1 parent b09964d commit 442283c

2 files changed

Lines changed: 96 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ with.
1010

1111
## My JavaScript Demos - I Love JavaScript!
1212

13+
* [Using AbortController To Debounce setTimeout() Calls](https://bennadel.github.io/JavaScript-Demos/demos/abort-timer/)
1314
* [Dynamically Creating Script Tags With Umbrella JS](https://bennadel.github.io/JavaScript-Demos/demos/umbrella-js-script-element/)
1415
* [Umbrella JS - A Light-Weight Replacement For jQuery](https://bennadel.github.io/JavaScript-Demos/demos/umbrella-js/)
1516
* [Applying Multiple Animation @keyframes To Support Prefers-Reduced-Motion In CSS](https://bennadel.github.io/JavaScript-Demos/demos/four-sided-scale-reduced-motion/)

demos/abort-timer/index.htm

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>
6+
Using AbortController To Debounce setTimeout() Calls
7+
</title>
8+
</head>
9+
<body>
10+
11+
<h1>
12+
Using AbortController To Debounce setTimeout() Calls
13+
</h1>
14+
15+
<button>
16+
Click Me
17+
</button>
18+
19+
<!-- Load scripts. -->
20+
<script type="text/javascript" src="../../vendor/umbrella/3.3.0/umbrella-3.3.0.min.js"></script>
21+
<script type="text/javascript" src="../../vendor/umbrella/jquery-compat.js"></script>
22+
<script type="text/javascript" charset="utf-8">
23+
24+
// HISTORICALLY, if we wanted to DEBOUNCE A TIMER, we would store a reference to
25+
// the timeoutID (the return value of the timer/interval functions). In this
26+
// case, we're going to use the same exactly technique; only, instead of storing
27+
// a timeoutID, we're storing a reference to an AbortController.
28+
var abortController = null;
29+
30+
u( "button" ).click(
31+
function handleClick() {
32+
33+
// HISTORICALLY, when debouncing clicks on the button, we would call the
34+
// clearTimeout() function right before setting up the timer. In this
35+
// case, since we're using the AbortController as the underlying control
36+
// mechanism, we're going to call .abort() instead.
37+
abortController?.abort();
38+
abortController = new AbortController();
39+
40+
setAbortableTimeout(
41+
function logTimeout() {
42+
43+
console.log( "Timer executed at %s \u{1F4AA}!", Date.now() );
44+
45+
},
46+
1000,
47+
abortController.signal
48+
);
49+
50+
}
51+
);
52+
53+
// --------------------------------------------------------------------------- //
54+
// --------------------------------------------------------------------------- //
55+
56+
/**
57+
* I create a timer that can be canceled using the optional AbortSignal.
58+
*/
59+
function setAbortableTimeout( callback, delayInMilliseconds, signal ) {
60+
61+
// When the calling context triggers an abort, we need to listen to for it so
62+
// that we can turn around and clear the internal timer.
63+
// --
64+
// NOTE: We're creating a proxy callback to remove this event-listener once
65+
// the timer executes. This way, our event-handler never gets invoked if
66+
// there's nothing for it to actually do. Also note that the "abort" event
67+
// will only ever get emitted once, regardless of how many times the calling
68+
// context tries to invoke .abort() on its AbortController.
69+
signal?.addEventListener( "abort", handleAbort );
70+
71+
// Setup our internal timer that we can clear-on-abort.
72+
var internalTimer = setTimeout( internalCallback, delayInMilliseconds );
73+
74+
// -- Internal methods. -- //
75+
76+
function internalCallback() {
77+
78+
signal?.removeEventListener( "abort", handleAbort );
79+
callback();
80+
81+
}
82+
83+
function handleAbort() {
84+
85+
console.warn( "Canceling timer (%s) via signal abort.", internalTimer );
86+
clearTimeout( internalTimer );
87+
88+
}
89+
90+
}
91+
92+
</script>
93+
94+
</body>
95+
</html>

0 commit comments

Comments
 (0)