1
0
Fork 0
mirror of synced 2024-09-18 18:28:33 +12:00
budibase/packages/frontend-core/src/utils/utils.js

88 lines
2.2 KiB
JavaScript

/**
* Utility to wrap an async function and ensure all invocations happen
* sequentially.
* @param fn the async function to run
* @return {Promise} a sequential version of the function
*/
export const sequential = fn => {
let queue = []
return (...params) => {
return new Promise((resolve, reject) => {
queue.push(async () => {
let data, error
try {
data = await fn(...params)
} catch (err) {
error = err
}
queue.shift()
if (queue.length) {
queue[0]()
}
if (error) {
reject(error)
} else {
resolve(data)
}
})
if (queue.length === 1) {
queue[0]()
}
})
}
}
/**
* Utility to debounce an async function and ensure a minimum delay between
* invocations is enforced.
* @param callback an async function to run
* @param minDelay the minimum delay between invocations
* @returns {Promise} a debounced version of the callback
*/
export const debounce = (callback, minDelay = 1000) => {
let timeout
return async (...params) => {
return new Promise(resolve => {
if (timeout) {
clearTimeout(timeout)
}
timeout = setTimeout(async () => {
resolve(await callback(...params))
}, minDelay)
})
}
}
/**
* Utility to throttle invocations of a synchronous function. This is better
* than a simple debounce invocation for a number of reasons. Features include:
* - First invocation is immediate (no initial delay)
* - Every invocation has the latest params (no stale params)
* - There will always be a final invocation with the last params (no missing
* final update)
* @param callback
* @param minDelay
* @returns {Function} a throttled version function
*/
export const throttle = (callback, minDelay = 1000) => {
let lastParams
let stalled = false
let pending = false
const invoke = (...params) => {
lastParams = params
if (stalled) {
pending = true
return
}
callback(...lastParams)
stalled = true
setTimeout(() => {
stalled = false
if (pending) {
pending = false
invoke(...lastParams)
}
}, minDelay)
}
return invoke
}