Skip to content

Commit 01a105d

Browse files
committed
documented and commented debounce method
to prevent misuse
1 parent 692ead8 commit 01a105d

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

src/Fabulous/Cmd.fs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,27 +188,41 @@ module Cmd =
188188
let inline msgOption (task: Task<'msg option>) =
189189
OfAsync.msgOption(task |> Async.AwaitTask)
190190

191-
/// Command to issue a message if no other message has been issued within the specified timeout
191+
/// <summary>Creates a factory for Commands that dispatch a message only
192+
/// if the factory produces no other Command within the specified timeout.
193+
/// Helps control how often a message is dispatched by delaying the dispatch after a period of inactivity.
194+
/// Useful for handling noisy inputs like keypresses or scrolling, and preventing too many actions in a short time, like rapid button clicks.
195+
/// Note that this creates an object with internal state and is intended to be used per Program or longer-running background process
196+
/// rather than once per message in the update function.</summary>
197+
/// <param name="timeout">The time to wait for the next Command from the factory in milliseconds.</param>
198+
/// <param name="fn">Maps a factory input value to a message for delayed dispatch.</param>
199+
/// <returns>A Command factory function that maps an input value to a "sleeper" Command which dispatches a delayed message (mapped from the value).
200+
/// This command is cancelled if the factory produces another Command within the specified timeout; otherwise it succeeds and the message is dispatched.</returns>
192201
let debounce (timeout: int) (fn: 'value -> 'msg) : 'value -> Cmd<'msg> =
193-
let funLock = obj()
194-
let mutable cts: CancellationTokenSource = null
202+
let funLock = obj() // ensures safe access to resources shared across different threads
203+
let mutable cts: CancellationTokenSource = null // if set, allows cancelling the last issued Command
195204

205+
// return a factory function mapping input values to "sleeper" Commands with delayed dispatch
196206
fun (value: 'value) ->
197207
[ fun dispatch ->
198208
lock funLock (fun () ->
209+
// cancel the last sleeping Command issued earlier from this factory
199210
if cts <> null then
200211
cts.Cancel()
201212
cts.Dispose()
202213

214+
// make cancellation available to the factory's next Command
203215
cts <- new CancellationTokenSource()
204216

217+
// asynchronously wait for the specified time before dispatch
205218
Async.Start(
206219
async {
207220
do! Async.Sleep(timeout)
208221

209222
lock funLock (fun () ->
210223
dispatch(fn value)
211224

225+
// done; invalidate own cancellation token
212226
if cts <> null then
213227
cts.Dispose()
214228
cts <- null)

0 commit comments

Comments
 (0)