ðŋ # identity functor / applicative / monad / maybe
Mathlessly journey from a basic Identity Functor to a Maybe Monad with an Applicative in-between.
Just(['world', 'hello'])
.map(x => x.reverse())
.map(x => x.join(', '))
.map(x => x + '!')
.valueOf()
ð # finite state-machine
Banish status booleans (or derive them from something predictable) with a finite state-machine.
const { send, current } = StateMachine({
chart: {
idle: { REQUEST: 'loading' },
loading: { DONE: 'complete' }
},
onTransition: console.log
})
send('REQUEST')
# message-bus
Use the existing browser events API to implement a message-bus.
on('update-store', () => {
console.log('store-updated!')
})
emit('update-store')
# reducers / transducers / compose
Build a map and filter transducer little by little, compose them, and avoid talking about math.
const onlyIntegers = filter(isInteger)
const doubleNumbers = map(x => x * 2)
const addOne = map(x => x + 1)
;[1, 2, undefined, 3].reduce(
intoArray(
onlyIntegers,
doubleNumbers,
addOne
),
[]
)
# cancelling promises
Three ways of cancelling promises: Using Revokable functions, Promises, and AbortController.
signal.addEventListener(
'abort',
() => {
reject(new Error('Cancelled'))
},
{ once: true }
)
# pooling / limiting promises
Use Set to implement a Promise API that limits the number of concurrently running tasks.
const add = makePromisePool(2)
Promise.allSettled([
add(() => hold(3).then(log)),
add(() => hold(1).then(log)),
add(() => hold(2).then(log))
])
# promise retrying
Take a function that creates a promise and retry it automatically if it fails. Memoize it to avoid duplicate instances.
const getUser = Memoize(
(id, invalidate) => {
const user = fetchWithRetries(3, id)
user.catch(invalidate)
return user
}
)
# memoizer / caching / invalidation
If your function or promise is slow but predictable, wrap it in a memoizer to put it behind a cache.
const getValue = Memoize(
(key, invalidate) => {
setTimeout(invalidate, seconds(30))
return thisWillTakeAWhile(key)
}
)
const value = getValue(42)
# debouncing / throttling
Treat repeated events happening across short periods of time as a single event with debouncing and throttling.
const [debounce, cancel] =
makeDebouncer(
seconds(1),
() => console.log('done')
)
# array sorting callbacks
Create a factory that produces sorting functions you can apply to arrays of numbers or objects.
const numbers = [3, 2, 1]
.sort(ByNumber())
const objects =
[
{ id: 3, name: 'three' },
{ id: 2, name: 'two' },
{ id: 1, name: 'one' }
]
.sort(ByNumber('id'))
# forEach / break / continue / @@iterator
Loops of the standard and functional variety, breaking out of them, and skipping iterations.
let count = 0
oneThousandItems().some((_, index) => {
if (index > 499) {
return true
}
count = count + 1
})