From 7bba1921c8751864b72e8b22c3b7e39dacaf004a Mon Sep 17 00:00:00 2001 From: Kyle Simpson Date: Tue, 3 Sep 2024 03:57:05 -0500 Subject: [PATCH] adding docs --- README.md | 85 +++++++++++++++++++++++++++++++++++++++++++----- package.json | 2 +- src/scheduler.js | 2 +- 3 files changed, 79 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index eac26d5..84e1ac5 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,15 @@ [![npm Module](https://badge.fury.io/js/@byojs%2Fscheduler.svg)](https://www.npmjs.org/package/@byojs/scheduler) [![License](https://img.shields.io/badge/license-MIT-a1356a)](LICENSE.txt) -**Scheduler** ... // TODO +**Scheduler** is a tool to manage *async scheduling* (debouncing, throttling) of repeated tasks. ```js -// TODO +var debouncer = Scheduler(100,500); +var throttler = Scheduler(300,300); + +window.addEventListener("scroll",() => debouncer(onScroll)); + +button.addEventListener("click",() => throttler(onButtonClick)); ``` ---- @@ -17,7 +22,21 @@ ## Overview -The main purpose of **Scheduler** is... // TODO +The main purpose of **Scheduler** is to provide [debouncing and throttling](https://css-tricks.com/debouncing-throttling-explained-examples/) controls for managing async task scheduling. Both scheduling schemes reduce how many repeated calls to a single function will be processed, over a defined interval of time, but use different strategies for determining when to schedule those calls. And both strategies may operate in two forms: *leading* and *trailing*. + +### Throttling + +Throttling prevents a repeated function call from being processed more than once per defined interval of time (e.g., 100ms); an interval timer is started with the *first call* (which resets after each interval transpires). + +With leading throttling, the initial call is processed immediately, and any subsequent call attempts, during the interval, will be ignored. With trailing throttling, only the last call is processed, *after* the full interval has transpired (since the first attempted call). + +### Debouncing + +Debouncing resets the delay interval with each attempted call of a function, meaning that the delay of processing an initial attempted call will continue to increase (unbounded), with each subsequent call attempt during the defined interval. + +With leading debouncing, the initial call is immediately processed, after which subsequent calls are debounced; once a full interval transpires without attempted calls, the most recent call is processed. With trailing debouncing, no initial call is processed. + +Debouncing could effectively delay a call being processed indefinitely, as long as at least one call attempt is made during each defined interval of time. So, you may optionally set an upper bound for the total debouncing delay, after which the most recent call will be processed and the debouncing interval reset. ## Deployment / Import @@ -36,7 +55,7 @@ If you are using a bundler (Astro, Vite, Webpack, etc) for your web application, Just `import` like so: ```js -import { /* TODO */ } from "@byojs/scheduler"; +import Scheduler from "@byojs/scheduler"; ``` The bundler tool should pick up and find whatever files (and dependencies) are needed. @@ -58,20 +77,70 @@ If you are not using a bundler (Astro, Vite, Webpack, etc) for your web applicat Now, you'll be able to `import` the library in your app in a friendly/readable way: ```js -import { /* TODO */ } from "scheduler"; +import Scheduler from "scheduler"; ``` **Note:** If you omit the above *scheduler* import-map entry, you can still `import` **Scheduler** by specifying the proper full path to the `scheduler.mjs` file. ## Scheduler API -The API provided by **Scheduler**... // TODO +The API provided by **Scheduler** is a single function -- the default export of the module. + +This function receives one to three arguments, to initialize a scheduler instance -- represented by another function as its return value -- using either [the throttle strategy](#throttling) or [the debounce strategy](#debouncing). + +To initialize an unbounded-debounce scheduler (in *leading* or *trailing* mode): + +```js +// leading unbounded debounce +var debouncer1 = Scheduler(250); + +// trailing unbounded debounce +var debouncer2 = Scheduler(250,Infinity,/*leading=*/false); +``` + +**Note:** The second argument represents the upper bound for total debouncing delay; `Infinity` (default) allows unbounded debouncing delay. + +To initialize a bounded-debounce scheduler (in *leading* or *trailing* mode): ```js -// .. TODO +// leading bounded (400ms) debounce +var debouncer3 = Scheduler(250,400); + +// trailing bounded (400ms) debounce +var debouncer4 = Scheduler(250,400,/*leading=*/false); ``` -// TODO +To initialize a throttle scheduler (in *leading* or *trailing* mode): + +```js +// leading throttle +var throttler1 = Scheduler(250,250); + +// trailing throttle +var throttler2 = Scheduler(250,250,/*leading=*/false); +``` + +**Note:** As shown, the throttling strategy is activated by passing the same value for the first two arguments (delay and upper-bound). + +---- + +Once you've setup a scheduler instance, you can schedule function calls by passing the (same) function value in (each time): + +```js +debouncer1(someFunc); + +// later (but within 250ms of previous call) +debouncer1(someFunc); + +// later (but within 250ms of previous call) +debouncer1(someFunc); +``` + +In this snippet, `someFunc` will only be called once (with no arguments), ~250ms after the last call (within the interval) to `debouncer1()`. + +The same scheduler instance can be used for debouncing/throttling as many different functions as desired, assuming the timing settings should apply for all of them. + +**Warning:** The internal tracking of repeated and async scheduled calls is based on function reference identity. If you pass an inline function expression (such as an `=>` arrow), the function reference will be different each time, and will be treated as entirely separate functions -- thereby defeating the debouncing/throttling. Make sure to use the same stable function reference for all scheduling-related invocations of the scheduler instance function. ## Re-building `dist/*` diff --git a/package.json b/package.json index b8644b8..088e764 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@byojs/scheduler", "description": "Throttle/debounce scheduler", - "version": "0.0.0-preA", + "version": "0.0.0-20240903035700", "exports": { "./": "./dist/scheduler.mjs" }, diff --git a/src/scheduler.js b/src/scheduler.js index 9b2d9f9..d086c3b 100644 --- a/src/scheduler.js +++ b/src/scheduler.js @@ -3,7 +3,7 @@ export default Scheduler; // *********************** -function Scheduler(debounceMin,throttleMax,leading = false) { +function Scheduler(debounceMin,throttleMax = Infinity,leading = false) { throttleMax = Math.max(debounceMin,throttleMax); var entries = new WeakMap();