* @public * @param {(Function)} fn * @param {number} [delay=0] Unit: ms. * @param {boolean} [debounce=false] * true: If call interval less than `delay`, only the last call works. * false: If call interval less than `delay, call works on fixed rate. * @return {(Function)} throttle
(fn, delay, debounce)
| 24920 | * @return {(Function)} throttled fn. |
| 24921 | */ |
| 24922 | function throttle(fn, delay, debounce) { |
| 24923 | |
| 24924 | var currCall; |
| 24925 | var lastCall = 0; |
| 24926 | var lastExec = 0; |
| 24927 | var timer = null; |
| 24928 | var diff; |
| 24929 | var scope; |
| 24930 | var args; |
| 24931 | var debounceNextCall; |
| 24932 | |
| 24933 | delay = delay || 0; |
| 24934 | |
| 24935 | function exec() { |
| 24936 | lastExec = (new Date()).getTime(); |
| 24937 | timer = null; |
| 24938 | fn.apply(scope, args || []); |
| 24939 | } |
| 24940 | |
| 24941 | var cb = function () { |
| 24942 | currCall = (new Date()).getTime(); |
| 24943 | scope = this; |
| 24944 | args = arguments; |
| 24945 | var thisDelay = debounceNextCall || delay; |
| 24946 | var thisDebounce = debounceNextCall || debounce; |
| 24947 | debounceNextCall = null; |
| 24948 | diff = currCall - (thisDebounce ? lastCall : lastExec) - thisDelay; |
| 24949 | |
| 24950 | clearTimeout(timer); |
| 24951 | |
| 24952 | // Here we should make sure that: the `exec` SHOULD NOT be called later |
| 24953 | // than a new call of `cb`, that is, preserving the command order. Consider |
| 24954 | // calculating "scale rate" when roaming as an example. When a call of `cb` |
| 24955 | // happens, either the `exec` is called dierectly, or the call is delayed. |
| 24956 | // But the delayed call should never be later than next call of `cb`. Under |
| 24957 | // this assurance, we can simply update view state each time `dispatchAction` |
| 24958 | // triggered by user roaming, but not need to add extra code to avoid the |
| 24959 | // state being "rolled-back". |
| 24960 | if (thisDebounce) { |
| 24961 | timer = setTimeout(exec, thisDelay); |
| 24962 | } |
| 24963 | else { |
| 24964 | if (diff >= 0) { |
| 24965 | exec(); |
| 24966 | } |
| 24967 | else { |
| 24968 | timer = setTimeout(exec, -diff); |
| 24969 | } |
| 24970 | } |
| 24971 | |
| 24972 | lastCall = currCall; |
| 24973 | }; |
| 24974 | |
| 24975 | /** |
| 24976 | * Clear throttle. |
| 24977 | * @public |
| 24978 | */ |
| 24979 | cb.clear = function () { |
no outgoing calls
no test coverage detected