RateLimitCb.coffee 2.3 KB

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