debounce.js 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. var assign = require('./assign')
  2. /**
  3. * 函数去抖;当被调用 n 毫秒后才会执行,如果在这时间内又被调用则将重新计算执行时间
  4. *
  5. * @param {Function} callback 回调
  6. * @param {Number} wait 多少秒毫
  7. * @param {Object} options 参数{leading: 是否在之前执行, trailing: 是否在之后执行}
  8. * @return {Function}
  9. */
  10. function debounce (callback, wait, options) {
  11. var args = null
  12. var context = null
  13. var opts = typeof options === 'boolean' ? { leading: options, trailing: !options } : assign({ leading: false, trailing: true }, options)
  14. var runFlag = false
  15. var timeout = null
  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. gcFn()
  26. }
  27. var endFn = function () {
  28. if (optLeading === true) {
  29. timeout = null
  30. }
  31. if (runFlag) {
  32. gcFn()
  33. return
  34. }
  35. if (optTrailing === true) {
  36. runFn()
  37. return
  38. }
  39. gcFn()
  40. }
  41. var cancelFn = function () {
  42. var rest = timeout !== null
  43. if (rest) {
  44. clearTimeout(timeout)
  45. }
  46. gcFn()
  47. timeout = null
  48. runFlag = false
  49. return rest
  50. }
  51. var debounced = function () {
  52. runFlag = false
  53. args = arguments
  54. context = this
  55. if (timeout === null) {
  56. if (optLeading === true) {
  57. runFn()
  58. }
  59. } else {
  60. clearTimeout(timeout)
  61. }
  62. timeout = setTimeout(endFn, wait)
  63. }
  64. debounced.cancel = cancelFn
  65. return debounced
  66. }
  67. module.exports = debounce