4 people like it.

debounce for F# Fable

a debounce function for F# Fable

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
// this kind of debouncer is part of the awesome F# Fabulous Library
// source: https://github.com/fsprojects/Fabulous/issues/161
// but modified for use in F# Fable

open System.Collections.Generic

let debounce<'T> =
    let mutable memoizations = Dictionary<string, int>(HashIdentity.Structural)

    fun (timeout: int) (fn: 'T -> unit) value ->
        let key = fn.ToString()
        // Cancel previous debouncer
        match memoizations.TryGetValue(key) with
        | true, timeoutId -> Fable.Core.JS.clearTimeout timeoutId
        | _ -> ()

        // Create a new timeout and memoize it
        let timeoutId = 
            Fable.Core.JS.setTimeout 
                (fun () -> 
                    memoizations.Remove(key) |> ignore
                    fn value
                ) 
                timeout
        memoizations.[key] <- timeoutId

open Fable.Core.JS
open Fable.Core.JsInterop

open Browser.Types

let input:HTMLInputElement = Browser.Dom.document.createElement("input") :?> HTMLInputElement
input.``type`` <- "text"
input.oninput <- debounce 1250 (fun e -> console.log(e.target?value))
Browser.Dom.document.body.appendChild(input) |> ignore

let input2:HTMLInputElement = Browser.Dom.document.createElement("input") :?> HTMLInputElement
input2.``type`` <- "text"
input2.oninput <- debounce 1000 (fun e -> console.log(e.target?value))
Browser.Dom.document.body.appendChild(input2) |> ignore
namespace System
namespace System.Collections
namespace System.Collections.Generic
val debounce<'T> : (int -> ('T -> unit) -> 'T -> unit)
val mutable memoizations : Dictionary<string,int>
Multiple items
type Dictionary<'TKey,'TValue> =
  new : unit -> Dictionary<'TKey, 'TValue> + 7 overloads
  member Add : key:'TKey * value:'TValue -> unit
  member Clear : unit -> unit
  member Comparer : IEqualityComparer<'TKey>
  member ContainsKey : key:'TKey -> bool
  member ContainsValue : value:'TValue -> bool
  member Count : int
  member EnsureCapacity : capacity:int -> int
  member GetEnumerator : unit -> Enumerator<'TKey, 'TValue>
  member GetObjectData : info:SerializationInfo * context:StreamingContext -> unit
  ...
  nested type Enumerator
  nested type KeyCollection
  nested type ValueCollection

--------------------
Dictionary() : Dictionary<'TKey,'TValue>
Dictionary(capacity: int) : Dictionary<'TKey,'TValue>
Dictionary(comparer: IEqualityComparer<'TKey>) : Dictionary<'TKey,'TValue>
Dictionary(dictionary: IDictionary<'TKey,'TValue>) : Dictionary<'TKey,'TValue>
Dictionary(collection: IEnumerable<KeyValuePair<'TKey,'TValue>>) : Dictionary<'TKey,'TValue>
Dictionary(capacity: int, comparer: IEqualityComparer<'TKey>) : Dictionary<'TKey,'TValue>
Dictionary(dictionary: IDictionary<'TKey,'TValue>, comparer: IEqualityComparer<'TKey>) : Dictionary<'TKey,'TValue>
Dictionary(collection: IEnumerable<KeyValuePair<'TKey,'TValue>>, comparer: IEqualityComparer<'TKey>) : Dictionary<'TKey,'TValue>
Multiple items
val string : value:'T -> string

--------------------
type string = System.String
Multiple items
val int : value:'T -> int (requires member op_Explicit)

--------------------
type int = int32

--------------------
type int<'Measure> = int
module HashIdentity

from Microsoft.FSharp.Collections
val Structural<'T (requires equality)> : IEqualityComparer<'T> (requires equality)
val timeout : int
val fn : ('T -> unit)
type unit = Unit
val value : 'T
val key : string
System.Object.ToString() : string
Dictionary.TryGetValue(key: string, value: byref<int>) : bool
val timeoutId : int
namespace Fable
namespace Fable.Core
module JS

from Fable.Core
val clearTimeout : token:int -> unit
val setTimeout : callback:(unit -> unit) -> ms:int -> int
Dictionary.Remove(key: string) : bool
(extension) IDictionary.Remove<'TKey,'TValue>(key: 'TKey, value: byref<'TValue>) : bool
Dictionary.Remove(key: string, value: byref<int>) : bool
val ignore : value:'T -> unit
module JsInterop

from Fable.Core
namespace Browser
namespace Browser.Types
val input : HTMLInputElement
type HTMLInputElement =
  interface
    inherit HTMLElement
    abstract member checkValidity : unit -> bool
    abstract member accept : string
    abstract member align : string
    abstract member alt : string
    abstract member autocomplete : string
    abstract member autofocus : bool
    abstract member border : string
    abstract member checked : bool
    abstract member complete : bool
    ...
  end
module Dom

from Browser
val document : Document
property HTMLElement.oninput: Event -> unit with get, set
val e : Event
val console : Console
abstract member Console.log : [<System.ParamArray>] optionalParams:obj [] -> unit
property Event.target: EventTarget with get, set
val input2 : HTMLInputElement
Raw view Test code New version

More information

Link:http://fssnip.net/85O
Posted:2 years ago
Author:Daniel Hardt
Tags: #fable , #debounce