Skip to content

dominicletz/debouncer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Debouncer Build

Debouncer module to reduce frequency of function calls to alerts, updates and similar. It supports four different modes:

  • apply() - For delayed triggers, e.g. to trigger an autocomplete action
  • immediate() - For reducing frequency of events, the first event per interval is delivered immediately, e.g. trigger data processing tasks
  • immediate2() - Similiar to immediate but never delays events, either forwards them or ignores them, e.g. to trigger alert emails
  • delay() - Only triggers an event after the timeout period, any further event delays the trigger. E.g. to detect data streams that ended actvitiy

Usage Example

  Debouncer.apply(SomeKey, fn() -> 
    IO.puts("Hello World, debounced will appear in 5 seconds") 
  end)
  Debouncer.immediate(OtherKey, fn() -> 
    IO.puts("Hello World, will appear immediate, but not again within 5 seconds") 
  end)

Behaviour Graph

EVENT        X1---X2------X3-------X4----------
TIMEOUT      ----------|----------|----------|-
===============================================
apply()      ----------X2---------X3---------X4
immediate()  X1--------X2---------X3---------X4
immediate2() X1-----------X3-------------------
delay()      --------------------------------X4

This graph represents when the different variants fire an event respectively on a timeline. In code the first line would look like this:

fn ->
  Debouncer.apply(SomeKey, fn() -> IO.puts("X1") end, 1000)
  Process.sleep(500)
  Debouncer.apply(SomeKey, fn() -> IO.puts("X2") end, 1000)
  Process.sleep(800)
  Debouncer.apply(SomeKey, fn() -> IO.puts("X3") end, 1000)
  Process.sleep(900)
  Debouncer.apply(SomeKey, fn() -> IO.puts("X4") end, 1000)
  Process.sleep(1200)
end.()

> X2
> X3
> X4

Shorthands

When using Module-Function-Argument tuples as callbacks (aka mfa) it can be convenient to skip the key and use the mfa itself as key:

# Call later() function immediately with the default 5 second debounce:
Debouncer.immediate({__MODULE__, :later, []})

# Call later() function immediately with 1 second debounce:
Debouncer.immediate({__MODULE__, :later, []}, 1_000)

# Same but in using method binding
Debouncer.immediate(&later/0, 1_000)

WARNING

Don't use in-place fun definitions in the shorthand, as those not work as unique-key because each call will be a different instance. So the debounce counting won't work.

Example:

# Because (`fn -> 1 end != fn -> 1 end`) don't do this:
Debouncer.immediate(fn -> later() end, 1_000)

Installation

The debouncer can be installed by adding debouncer to your list of dependencies in mix.exs:

def deps do
  [
    {:debouncer, "~> 0.1"}
  ]
end

The debouncer is an application and will start a GenServer to trigger the events. To include the Application in your release add it to your extra applications:

  def application do
    [
      mod: {Your.Application, []},
      extra_applications: [:debouncer]
    ]
  end

If it's not started it will try to start itself on usage.

The docs can be found at https://hexdocs.pm/debouncer.

Remarks

The delay() behaviour should be the same as in Michal Muskalas Debounce implementation https://github.com/michalmuskala/debounce

About

Elixir debouncer library

Topics

Resources

License

Stars

Watchers

Forks

Contributors 2

  •  
  •  

Languages