RateLimitCb.coffee 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. last_time = {}
  2. calling = {}
  3. call_after_interval = {}
  4. # Rate limit function call and don't allow to run in parallel (until callback is called)
  5. window.RateLimitCb = (interval, fn, args=[]) ->
  6. cb = -> # Callback when function finished
  7. left = interval - (Date.now() - last_time[fn]) # Time life until next call
  8. # console.log "CB, left", left, "Calling:", calling[fn]
  9. if left <= 0 # No time left from rate limit interval
  10. delete last_time[fn]
  11. if calling[fn] # Function called within interval
  12. RateLimitCb(interval, fn, calling[fn])
  13. delete calling[fn]
  14. else # Time left from rate limit interval
  15. setTimeout (->
  16. delete last_time[fn]
  17. if calling[fn] # Function called within interval
  18. RateLimitCb(interval, fn, calling[fn])
  19. delete calling[fn]
  20. ), left
  21. if last_time[fn] # Function called within interval
  22. calling[fn] = args # Schedule call and update arguments
  23. else # Not called within interval, call instantly
  24. last_time[fn] = Date.now()
  25. fn.apply(this, [cb, args...])
  26. window.RateLimit = (interval, fn) ->
  27. if not calling[fn]
  28. call_after_interval[fn] = false
  29. fn() # First call is not delayed
  30. calling[fn] = setTimeout (->
  31. if call_after_interval[fn]
  32. fn()
  33. delete calling[fn]
  34. delete call_after_interval[fn]
  35. ), interval
  36. else # Called within iterval, delay the call
  37. call_after_interval[fn] = true
  38. ###
  39. window.s = Date.now()
  40. window.load = (done, num) ->
  41. console.log "Loading #{num}...", Date.now()-window.s
  42. setTimeout (-> done()), 1000
  43. RateLimit 500, window.load, [0] # Called instantly
  44. RateLimit 500, window.load, [1]
  45. setTimeout (-> RateLimit 500, window.load, [300]), 300
  46. setTimeout (-> RateLimit 500, window.load, [600]), 600 # Called after 1000ms
  47. setTimeout (-> RateLimit 500, window.load, [1000]), 1000
  48. setTimeout (-> RateLimit 500, window.load, [1200]), 1200 # Called after 2000ms
  49. setTimeout (-> RateLimit 500, window.load, [3000]), 3000 # Called after 3000ms
  50. ###