useLoop.ts 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. import { WatchSource } from 'vue'
  2. export function useLoop(
  3. loopFunctions: (() => void | Promise<void>)[],
  4. interval: number | string,
  5. watchSources: (WatchSource | object)[] = []
  6. ) {
  7. let queryLoop: number | null = null
  8. let querying = false
  9. let stopFlag = false
  10. const startQuery = async () => {
  11. querying = true
  12. stopFlag = false
  13. await Promise.allSettled(loopFunctions.map(func => func()))
  14. if (stopFlag) {
  15. return
  16. }
  17. queryLoop = window.setTimeout(
  18. startQuery,
  19. typeof interval === 'string'
  20. ? LOOP_INTERVAL[interval]
  21. ? LOOP_INTERVAL[interval]
  22. : 15 * 1000
  23. : interval
  24. )
  25. }
  26. const stopQuery = () => {
  27. stopFlag = true
  28. if (queryLoop) {
  29. clearTimeout(queryLoop)
  30. queryLoop = null
  31. }
  32. querying = false
  33. }
  34. if (watchSources.length) {
  35. watch(watchSources, () => {
  36. stopQuery()
  37. startQuery()
  38. })
  39. }
  40. onMounted(() => {
  41. if (querying) {
  42. return
  43. }
  44. startQuery()
  45. })
  46. onActivated(() => {
  47. if (querying) {
  48. return
  49. }
  50. startQuery()
  51. })
  52. onDeactivated(() => {
  53. stopQuery()
  54. })
  55. onBeforeUnmount(() => {
  56. stopQuery()
  57. })
  58. }