Created
September 27, 2019 15:09
-
-
Save sbatson5/507fb794fc90f62cb084bd53e632113d to your computer and use it in GitHub Desktop.
Throttling Vuex actions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import store from '@/store'; | |
/** | |
* A simple class we create just for tracking our running functions | |
*/ | |
class Concurrency { | |
get(key) { | |
return this[key] || {}; | |
} | |
set(key, value) { | |
this[key] = value; | |
} | |
}; | |
const concurrencyInstance = new Concurrency(); | |
/** | |
* | |
* @param {function} generatorFunction to be called | |
* @param {number} timeToWait time in milliseconds - default half a second | |
*/ | |
const throttle = (generatorFunction, timeToWait = 500) => { | |
// I explain how I got this convenient method in a blog post: | |
// https://medium.com/stories-from-upstatement/last-vuex-action-hero-f8482c985b27 | |
// Get the name of the last action called | |
const { name } = store.state.lastDispatchedAction; | |
// See if there is a stored function with the same name as the one we are trying | |
const instanceFunction = concurrencyInstance.get(name); | |
// If there is, stop it from running | |
if (instanceFunction.return) { | |
instanceFunction.return(); | |
} | |
// Reset it with the new version of the function we just received | |
const newInstance = generatorFunction(); | |
concurrencyInstance.set(name, newInstance); | |
// An internal function that will actually execute our generator function | |
const run = async () => { | |
// Go to the next yield block | |
const result = newInstance.next(); | |
// Generator functions have a concept of `done` | |
// Which means they have completed any task written or been cancelled | |
if (result.done) { | |
return result.value; | |
} else { | |
// if it is not finished, wait for the promise to resolve and go onto the next promise | |
await result.value; | |
run(); | |
} | |
}; | |
// Wait a small amount of time before actually completing the function | |
// Meaning we won't ever call the same function more than once in a small period of time | |
setTimeout(run, timeToWait); | |
}; | |
export { throttle, concurrencyInstance }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment