throttle.js 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. var assign = require('./assign')
  2. /**
  3. * 节流函数;当被调用 n 毫秒后才会执行,如果在这时间内又被调用则至少每隔 n 秒毫秒调用一次该函数
  4. *
  5. * @param {Function} callback 回调
  6. * @param {Number} wait 多少秒毫
  7. * @param {Object} options 参数{leading: 是否在之前执行, trailing: 是否在之后执行}
  8. * @return {Function}
  9. */
  10. function throttle (callback, wait, options) {
  11. var args = null
  12. var context = null
  13. var runFlag = false
  14. var timeout = null
  15. var opts = assign({ leading: true, trailing: true }, options)
  16. var optLeading = opts.leading
  17. var optTrailing = opts.trailing
  18. var gcFn = function () {
  19. args = null
  20. context = null
  21. }
  22. var runFn = function () {
  23. runFlag = true
  24. callback.apply(context, args)
  25. timeout = setTimeout(endFn, wait)
  26. gcFn()
  27. }
  28. var endFn = function () {
  29. timeout = null
  30. if (runFlag) {
  31. gcFn()
  32. return
  33. }
  34. if (optTrailing === true) {
  35. runFn()
  36. return
  37. }
  38. gcFn()
  39. }
  40. var cancelFn = function () {
  41. var rest = timeout !== null
  42. if (rest) {
  43. clearTimeout(timeout)
  44. }
  45. gcFn()
  46. timeout = null
  47. runFlag = false
  48. return rest
  49. }
  50. var throttled = function () {
  51. args = arguments
  52. context = this
  53. runFlag = false
  54. if (timeout === null && optLeading === true) {
  55. runFn()
  56. return
  57. }
  58. if (optTrailing === true) {
  59. timeout = setTimeout(endFn, wait)
  60. }
  61. }
  62. throttled.cancel = cancelFn
  63. return throttled
  64. }
  65. module.exports = throttle