Underscore: рд╕реБрдЭрд╛рд╡: _.debounce рдФрд░ _.throttle рддрд░реНрдХреЛрдВ рдХреЛ рдХреИрд╕реЗ рд╕рдВрдпреЛрдЬрд┐рдд рдХрд░реЗрдВ, рдЗрд╕рдХреЗ рд▓рд┐рдП рдЕрддрд┐рд░рд┐рдХреНрдд рдкреИрд░рд╛рдореАрдЯрд░ рд▓реЗрддреЗ рд╣реИрдВ

рдХреЛ рдирд┐рд░реНрдорд┐рдд 22 рд╕рд┐рддре░ 2011  ┬╖  11рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: jashkenas/underscore

рдпрджрд┐ рдореИрдВ рдбрд┐рдмреЙрдиреНрд╕реНрдб рдлрд╝рдВрдХреНрд╢рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП _.debounce() рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ рдФрд░ рдлрд┐рд░ рдЗрд╕реЗ 3 рдЕрд▓рдЧ-рдЕрд▓рдЧ рддрд░реНрдХреЛрдВ рдХреЗ рд╕рд╛рде рдЙрддреНрддрд░рд╛рдзрд┐рдХрд╛рд░ рдореЗрдВ 3 рдмрд╛рд░ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реВрдВ, рддреЛ (v1.1.7) рдХреЗ рд░реВрдк рдореЗрдВ рд▓рд┐рдкрдЯреЗ рдкреЗрд▓реЛрдб рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЕрдВрддрддрдГ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рддрд░реНрдХреЛрдВ рдХреЗ рд╕рд╛рде рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ рддреАрд╕рд░рд╛ рдХреЙрд▓ - рдпрд╛рдиреА рдкрд╣рд▓рд╛ рдФрд░ рджреВрд╕рд░рд╛ рддрд░реНрдХ рдЦрд╛рд░рд┐рдЬ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдЕрдХреНрд╕рд░ рдорд╛рдиреНрдп рд╣реЛрддрд╛ рд╣реИ (рдФрд░ рдЖрдо рддреМрд░ рдкрд░ рдХреМрди рд╕реА рдХреБрдВрдЬреА рдбрд┐рдмрдЧрд┐рдВрдЧ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдПрдХ рдЙрдЪрд┐рдд рдбрд┐рдлрд╝реЙрд▓реНрдЯ) рдореИрдВ рдЦреБрдж рдХреЛ рддрд░реНрдХ рдЬрдорд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣рд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдореЗрд░реЗ рдкрд╛рд╕ рдПрдХ AJAX рдХреЙрд▓ рд╣реИ рдЬреЛ рдПрдХ рд╕рд╛рде рдХрдИ рдХреБрдВрдЬреА рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдмрдлрд░ рдХреЗ рд▓рд┐рдП рдмрд╣рд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ рдПрдХ рд╕реЗрдХрдВрдб рдХреЗ рд▓рд┐рдП рдЕрдк рдХреБрдВрдЬреА рдФрд░ рдлрд┐рд░ рдПрдХ рд╕рдВрдпреБрдХреНрдд рдЕрдиреБрд░реЛрдз рдЬрд╛рд░реА рдХрд░реЗрдВред

рдореЗрд░рд╛ рд╕реБрдЭрд╛рд╡ рдЗрд╕рд▓рд┐рдП рд╣реИ рдХрд┐ рдмрд╣рд╕ рдПрдХ рд╡реИрдХрд▓реНрдкрд┐рдХ рддреАрд╕рд░рд╛ "рдЧрдардмрдВрдзрди" рддрд░реНрдХ рд▓реЗрддрд╛ рд╣реИ рдЬрд┐рд╕реЗ 2 рддрд░реНрдХреЛрдВ рдХреЗ рд╕рд╛рде рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛,

  • рдкрд╣рд▓реА рдЕрдм рддрдХ рд╕рдВрдЪрд┐рдд рддрд░реНрдХреЛрдВ рдХреА рд╕реВрдЪреА рд╣реИ (рд╕рдВрднрд╡рддрдГ рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд - рдпрд╛рдиреА рдкрд╣рд▓реА рдХреЙрд▓ рдкрд░ рдХреЛрдИ рд╕реВрдЪреА рдирд╣реАрдВ)
  • рджреВрд╕рд░рд╛ рдирд╡реАрдирддрдо рдХреЙрд▓ рдХреЗ рд▓рд┐рдП рддрд░реНрдХреЛрдВ рдХреА рд╕реВрдЪреА рд╣реИ (рд╕рдВрднрд╡рддрдГ рдПрдХ рдЦрд╛рд▓реА рд╕реВрдЪреА)
    рдФрд░ рд╕рдВрдЪрд┐рдд рдЖрд░реНрдЧ рдХреА рдирдИ рд╕реВрдЪреА рд▓реМрдЯрд╛рддрд╛ рд╣реИред рдЬрдм рдкреЗрд▓реЛрдб рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ args рдХреА рд╕рдВрдЪрд┐рдд рд╕реВрдЪреА рд╕рд╛рдлрд╝ рд╣реЛ рдЬрд╛рддреА рд╣реИред

рдпрджрд┐ рдХрдВрдмрд╛рдЗрди рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдорд╛рди рдкрд╛рд╕ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдХрдВрдмрд╛рдЗрди рдореМрдЬреВрджрд╛ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рд╕рдВрд░рдХреНрд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ
function(acc, newargs) { return newargs; }
рд▓реЗрдХрд┐рди рдЖрдк рддрд░реНрдХреЛрдВ рдХреЗ рдкрд╣рд▓реЗ рд╕реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рднреА рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВ
function(acc, newargs) { return acc || newargs; }
рдпрд╛ рдореИрдВ рдЬреЛ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рд╡рд╣ рдмрд╕ рд╕рднреА рддрд░реНрдХреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдирд╛ рд╣реИ
function(acc,newargs) { return (acc || []).concat(newargs); }
рдФрд░ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЕрдиреНрдп рд▓реЛрдЧ рдХреБрдЫ рдХрдЯреНрдЯрд░ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ

рдЗрд╕рдХреЗ рд▓рд┐рдП рдЖрдВрддрд░рд┐рдХ рд╕реАрдорд╛ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрд░рд┐рд╡рд░реНрддрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА

  // Internal function used to implement `_.throttle` and `_.debounce`.
  var limit = function(func, wait, debounce, combine) {
    var timeout, allargs;
    return function() {
      var context = this;
      allargs = combine(allargs,  slice.call(arguments,0))
      var throttler = function() {
        timeout = null;
        var args = allargs;
        allargs = undefined;
        func.apply(context, args);
      };
      if (debounce) clearTimeout(timeout);
      if (debounce || !timeout) timeout = setTimeout(throttler, wait);
    };
  };

рдФрд░ рдлрд┐рд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рд╣реЛрдиреЗ рдкрд░ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рди рдХреЗ рд╕рд╛рде рдирдП рддрд░реНрдХ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рдФрд░ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣рд╕ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрдиред

  _.debounce = function(func, wait, combine) {
    return limit(func, wait, true, combine || function(acc,newargs) { return newargs; });
  };

рд╕рдВрдмрдВрдзрд┐рдд рдереНрд░реЙрдЯрд▓ рдлрд╝рдВрдХреНрд╢рди рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдЕрдХреЗрд▓реЗ рддрд░реНрдХреЛрдВ рдХреЗ рдкрд╣рд▓реЗ рд╕реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ (рдереНрд░реЙрдЯрд▓ рдкрд╣рд▓реА рдХреЙрд▓ рдХреЗ рдкреНрд░рддреАрдХреНрд╖рд╛ рдорд┐рд▓реАрд╕реЗрдХрдВрдб рдХреЗ рднреАрддрд░ рд╣реЛрдиреЗ рд╡рд╛рд▓реА рдХреЙрд▓реЛрдВ рдХреЛ рдкреНрд░рднрд╛рд╡реА рдврдВрдЧ рд╕реЗ рдЕрдирджреЗрдЦрд╛ рдХрд░рддрд╛ рд╣реИ рдФрд░ рддрд░реНрдХреЛрдВ рдХреЗ рдкрд╣рд▓реЗ рдХреЙрд▓ рд╕реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдмрд╣рд╕ рдкреНрд░рднрд╛рд╡реА рд░реВрдк рд╕реЗ рдкреНрд░рддреАрдХреНрд╖рд╛ рдЕрд╡рдзрд┐ рдХреЗ рднреАрддрд░ рд╣реЛрдиреЗ рд╡рд╛рд▓реА рдЕрдиреБрдХреНрд░рдо рдореЗрдВ рдЕрдВрддрд┐рдо рдХреЙрд▓ рдХреЛ рдЫреЛрдбрд╝рдХрд░ рд╕рднреА рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░рддрд╛ рд╣реИ рдПрдХ рджреВрд╕рд░реЗ рдХреЗ), рдЗрд╕рд▓рд┐рдП рдореИрдВ рд╡рд░реНрддрдорд╛рди рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдлрд┐рд░ рд╕реЗ рд╕рдВрд░рдХреНрд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдиреАрдЪреЗ рдХрд╛ рд╕реБрдЭрд╛рд╡ рджреВрдВрдЧрд╛

  _.throttle = function(func, wait, combine) {
    return limit(func, wait, false, combine || function(acc,newargs) { return acc || newargs; });
  };

рддрд░реНрдХ рд╕реВрдЪрд┐рдпреЛрдВ рдХреЛ рдмрдирд╛рдП рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЕрддреНрдпрдзрд┐рдХ рд░реИрдкрд░ рдХреЗ рдмрд┐рдирд╛ рдЗрд╕ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдпрд╣ рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рдФрд░ рд╕рдмрд╕реЗ рд╕рд╛рдорд╛рдиреНрдп рддрд░реАрдХрд╛ рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдпрд╣ рдЬрд╛рдирдиреЗ рдореЗрдВ рджрд┐рд▓рдЪрд╕реНрдкреА рд╣реЛрдЧреА рдХрд┐ рдЕрдВрдбрд░рд╕реНрдХреЛрд░ рдХреЛ рдмрджрд▓реЗ рдмрд┐рдирд╛ рдЗрд╕реЗ рд╣рд╛рд╕рд┐рд▓ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВред

enhancement wontfix

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдареАрдХ рд╣реИ, рдзрдорд╛рдХрд╛ рдХрд░рддреЗ рд░рд╣рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдХреЛрдИ рдЗрд╕реЗ рдХреБрдЫ рд╕рдордп рдмрд╛рдж рджреЗрдЦ рд░рд╣рд╛ рд╣реИ рдФрд░ рд╕реЛрдЪ рд░рд╣рд╛ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рдП, рддреЛ рдореБрдЭреЗ рд▓рдЧрд╛ рдХрд┐ рдпрд╣ рдмрд╣рд╕ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд┐рдП рдмрд┐рдирд╛ рд╕рдмрд╕реЗ рд╕рд╛рдл рддрд░реАрдХрд╛ рд╣реИ (рдореИрдВ рдЗрд╕реЗ _ рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдЬреЛрдбрд╝рддрд╛ рд╣реВрдВ, рдЕрдиреНрдп рдЗрд╕реЗ рдкрд╕рдВрдж рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ) рдкреНрд░рддрд┐)

_.mixin({
  debounceReduce: function(func, wait, combine) {
    var allargs,
        context,
        wrapper = _.debounce(function() {
            var args = allargs;
            allargs = undefined;
            func.apply(context, args);
        }, wait);
        return function() {
            context = this;
            allargs = combine.apply(context, [allargs,  Array.prototype.slice.call(arguments,0)]);
            wrapper();
        };
    }
})

рдпрд╣ рдПрдХ рд╡рд┐рд╡рд╛рджрд┐рдд рдлрд╝рдВрдХреНрд╢рди рджреЗрддрд╛ рд╣реИ рдЬрд┐рд╕рдХреЗ рддрд░реНрдХреЛрдВ рдХреЛ рдХрдореНрдмрд╛рдЗрди рдлрд╝рдВрдХреНрд╢рди рджреНрд╡рд╛рд░рд╛ рдХрдо рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП,

  delayLog = _.debounceReduce(function() { console.log(arguments); }, 5000, 
                              function(acc,args) { return (acc || []).concat(args); });
  delayLog(3,4);
  delayLog(7,8,9);

рдХреБрдЫ рд╕реЗрдХрдВрдб рдмрд╛рдж рдореЗрдВ рдХрдВрд╕реЛрд▓ рдХреЛ рдХреЙрд▓ рдХрд░реЗрдЧрд╛ред рд╕рд░рдгреА рдХреЗ рд╕рд╛рде рд▓реЙрдЧ рдЗрди рдХрд░реЗрдВ [3,4,7,8,9]

рд╕рднреА 11 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдореЗрд░реЗ рдЕрдкрдиреЗ рд╕реБрдЭрд╛рд╡ рдкрд░ рдЯрд┐рдкреНрдкрдгреА рдХрд░рддреЗ рд╣реБрдП, рдХреЙрд▓ рдЯреВ рдХреЙрдореНрдмрд┐рдиреЗрд╢рди () рдХреЛ рдкреЗрд▓реЛрдб рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рдорд╛рди рд╕рдВрджрд░реНрдн рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЗрд╕рд▓рд┐рдП

allargs = combine.apply(this, [allargs, slice.call(arguments,0)])

рдпрджрд┐ рддрд░реНрдХреЛрдВ рдХреЛ рд╕рдВрджрд░реНрдн рд╡рд╕реНрддреБ рддрдХ рдкрд╣реБрдБрдЪрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ ....

рдЕрдм рдорд╛рд╕реНрдЯрд░ рдкрд░ рдлрд┐рдХреНрд╕ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред throttle рдХреЛ рд╕рд╣реА рд╡реНрдпрд╡рд╣рд╛рд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдЬрд╣рд╛рдВ рдпрд╣ рд╣рдореЗрд╢рд╛ рдЖрдкрдХреЗ рддрд░реНрдХреЛрдВ рдХреА рдирд╡реАрдирддрдо рдкреНрд░рддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рддреБрд░рдВрдд рдПрдХ рдмрд╛рд░ рд╕рдХреНрд░рд┐рдп рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж рдкреНрд░рддреНрдпреЗрдХ N рд╕реЗрдХрдВрдб ... рдФрд░ N рд╕реЗрдХрдВрдб рдХреЗ рдмрд╛рдж рдЦреБрдж рдХреЛ рд░реАрд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ рдЕрдВрддрд┐рдо рдЕрдиреБрдЧрд╛рдореА рдЯреНрд░рд┐рдЧрд░ рд╣реБрдЖ рд╣реИред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдкрдХреА рдХрд░реАрдмреА рдЯрд┐рдкреНрдкрдгреА рдХрд┐рд╕реА рдЕрдиреНрдп рдореБрджреНрджреЗ (рд╢рд╛рдпрдж # 170) рдкрд░ рд▓рд╛рдЧреВ рд╣реЛрддреА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕ рдЕрдиреБрд░реЛрдз рджреНрд╡рд╛рд░рд╛ рдЙрдард╛рдпрд╛ рдЧрдпрд╛ рдореБрджреНрджрд╛ рдЕрднреА рднреА рдорд╛рд╕реНрдЯрд░ рдкрд░ рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИред
рд╕рдВрдпреБрдХреНрдд рд╣реЛрдиреЗ рд╡рд╛рд▓реА рдХреЙрд▓реЛрдВ рд╕реЗ рдмрд╣рд╕ рдпрд╛ рдереНрд░реЙрдЯрд▓ рдЬрдорд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрднреА рднреА рдХреЛрдИ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ, рдФрд░ рдореБрдЭреЗ рдЕрднреА рднреА рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдЙрдкрдпреЛрдЧреА рд╡реИрдХрд▓реНрдкрд┐рдХ рдЬреЛрдбрд╝ рд╣реИ рдЬреЛ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╕рдВрдпреЛрдЬрди рддрд░реНрдХ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рд╣реЛрдиреЗ рдкрд░ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдЕрдкрд░рд┐рд╡рд░реНрддрд┐рдд рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реИред

рдЖрд╣, рддреБрдо рд╕рд╣реА рд╣реЛред рддрд░реНрдХреЛрдВ рдХреЛ рдЬрдорд╛ рдХрд░рдирд╛ рдЕрдВрдбрд░рд╕реНрдХреЛрд░ рдХреЗ рджрд╛рдпрд░реЗ рд╕реЗ рдмрд╛рд╣рд░ рд╣реИ -- рдмреЗрдЭрд┐рдЭрдХ рдЕрдкрдиреЗ рд╕рдВрдЪрд┐рдд рдбреЗрдЯрд╛ рдХреЛ _.throttle рдФрд░ _.debounce рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХреЗ рдмрд╛рд╣рд░ рдХрд┐рд╕реА рдЕрдЪреНрдЫреА рдЬрдЧрд╣ рдкрд░ рд░рдЦреЗрдВред

рдпрд╣ рдЕрдлрд╝рд╕реЛрд╕ рдХреА рдмрд╛рдд рд╣реИ, рдореИрдВ рдмрд╣рд╕ рдХреЛ рдПрдХ рддрд░рд╣ рд╕реЗ рдЧреБрдирд╛-рдмрд╛рдПрдВ (рдХрдо) рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЯрд╛рдЗрдордЖрдЙрдЯ рдХреЗ рд╕рд╛рде рдХрдИ рдХреЙрд▓реЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рддрд╛ рд╣реВрдВ рдЗрд╕рд▓рд┐рдП рд╕рдВрдЪрд╛рдпрдХ ... рд▓реЗрдХрд┐рди рдпрд╣ рдЖрдкрдХреА рдХреЙрд▓ рд╣реИ :)

рдареАрдХ рд╣реИ, рдзрдорд╛рдХрд╛ рдХрд░рддреЗ рд░рд╣рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдХреЛрдИ рдЗрд╕реЗ рдХреБрдЫ рд╕рдордп рдмрд╛рдж рджреЗрдЦ рд░рд╣рд╛ рд╣реИ рдФрд░ рд╕реЛрдЪ рд░рд╣рд╛ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рдП, рддреЛ рдореБрдЭреЗ рд▓рдЧрд╛ рдХрд┐ рдпрд╣ рдмрд╣рд╕ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд┐рдП рдмрд┐рдирд╛ рд╕рдмрд╕реЗ рд╕рд╛рдл рддрд░реАрдХрд╛ рд╣реИ (рдореИрдВ рдЗрд╕реЗ _ рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдЬреЛрдбрд╝рддрд╛ рд╣реВрдВ, рдЕрдиреНрдп рдЗрд╕реЗ рдкрд╕рдВрдж рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ) рдкреНрд░рддрд┐)

_.mixin({
  debounceReduce: function(func, wait, combine) {
    var allargs,
        context,
        wrapper = _.debounce(function() {
            var args = allargs;
            allargs = undefined;
            func.apply(context, args);
        }, wait);
        return function() {
            context = this;
            allargs = combine.apply(context, [allargs,  Array.prototype.slice.call(arguments,0)]);
            wrapper();
        };
    }
})

рдпрд╣ рдПрдХ рд╡рд┐рд╡рд╛рджрд┐рдд рдлрд╝рдВрдХреНрд╢рди рджреЗрддрд╛ рд╣реИ рдЬрд┐рд╕рдХреЗ рддрд░реНрдХреЛрдВ рдХреЛ рдХрдореНрдмрд╛рдЗрди рдлрд╝рдВрдХреНрд╢рди рджреНрд╡рд╛рд░рд╛ рдХрдо рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП,

  delayLog = _.debounceReduce(function() { console.log(arguments); }, 5000, 
                              function(acc,args) { return (acc || []).concat(args); });
  delayLog(3,4);
  delayLog(7,8,9);

рдХреБрдЫ рд╕реЗрдХрдВрдб рдмрд╛рдж рдореЗрдВ рдХрдВрд╕реЛрд▓ рдХреЛ рдХреЙрд▓ рдХрд░реЗрдЧрд╛ред рд╕рд░рдгреА рдХреЗ рд╕рд╛рде рд▓реЙрдЧ рдЗрди рдХрд░реЗрдВ [3,4,7,8,9]

@schmerg - рдпрд╣ рдХрд╛рдлреА рдЙрдкрдпреЛрдЧреА рд▓рдЧ рд░рд╣рд╛ рд╣реИред рдХреНрдпрд╛ рдЖрдк рдЙрд╕ рдХреЛрдб рдХреЛ рдПрдордЖрдИрдЯреА рд▓рд╛рдЗрд╕реЗрдВрд╕ рдХреЗ рддрд╣рдд рд▓рд╛рдЗрд╕реЗрдВрд╕ рджреЗрдиреЗ рдХреЗ рдЗрдЪреНрдЫреБрдХ рд╣реЛрдВрдЧреЗ? (рдПрдХ "рд╣рд╛рдБ" рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрдЧрд╛!)

@markjaquith рдЬрд╝рд░реВрд░ рдмрд╛рдд - рд╣рд╛рдБред рдмрд╣реБрдд рдЦреБрд╢реА рд╣реБрдИ...

рдЕрдЧрд░ рдХреЛрдИ рд╕рд╛рде рдЖрддрд╛ рд╣реИ рдФрд░ рдЙрдкрд░реЛрдХреНрдд рдХреЗ рдЖрдзреБрдирд┐рдХ рдЬреЗрдПрд╕ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдЕрджреНрдпрддрди/рдЯрд┐рдкреНрдкрдгреА рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ:

_.mixin({
  debounceReduce(func, wait, combine) {
    let allArgs; // accumulator for args across calls

    // normally-debounced fn that we will call later with the accumulated args
    const wrapper = _.debounce(() => func(allArgs), wait);

    // what we actually return is this function which will really just add the new args to
    // allArgs using the combine fn
    return (...args) => {
      allArgs = combine(allArgs,  [...args]);
      wrapper();
    };
  },
});

@kmannislands рдЕрд░реЗ, рдЖрдкрдХрд╛ рд╕рдВрд╕реНрдХрд░рдг allArgs рдХреЛ wrapper() $ рдХреЗ рдЕрдВрджрд░ рд░реАрд╕реЗрдЯ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдмрд╛рдж рдореЗрдВ func() рдкрд░ рдХреЙрд▓ рдХрд░рдиреЗ рд╕реЗ args рдХреЗ рдРрддрд┐рд╣рд╛рд╕рд┐рдХ рдмреИрдЪреЛрдВ рдХреЗ рд╕рд╛рде-рд╕рд╛рде рд╡рд░реНрддрдорд╛рди рдмреИрдЪ рднреА рдкреНрд░рд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИред

рдХреНрдпрд╛ рдпрд╣ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП:

const wrapper = _.debounce(() => {
    const args = allArgs;
    allArgs = undefined;
    func(args);
}, wait);

@markjaquith +1

рд╕рд╛рде рд╣реА func( args ) рдореВрд▓ рд╕рдВрд╕реНрдХрд░рдг рд╕реЗ рдЕрд▓рдЧ рд╣реИ рдЬреЛ func.apply(context, args); рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред
рдкреВрд░реНрд╡ рдХреЗ рд▓рд┐рдП, args рдХрд╛ рдЙрдкрдпреЛрдЧ рд▓рдХреНрд╖реНрдп func() рдХреЗ рд░реВрдк рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрдмрдХрд┐ рдмрд╛рдж рдХреЗ _(рдореВрд▓ рдХреЛрдб)_ рдореЗрдВ рдЖрдкрдХреЛ рд╕рд╛рдорд╛рдиреНрдп рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ arguments рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдпрд╛ ( ...args ) рдПрдХ es6 рд╡рд╕рд╛ рддреАрд░ рд╕рдорд╛рд░реЛрд╣ рдореЗрдВред

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕