Underscore: μ œμ•ˆ: _.debounce 및 _.throttle은 인수λ₯Ό κ²°ν•©ν•˜λŠ” 방법에 λŒ€ν•΄ μΆ”κ°€ λ§€κ°œλ³€μˆ˜λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

에 λ§Œλ“  2011λ…„ 09μ›” 22일  Β·  11μ½”λ©˜νŠΈ  Β·  좜처: jashkenas/underscore

_.debounce()λ₯Ό μ‚¬μš©ν•˜μ—¬ λ””λ°”μš΄μŠ€λœ ν•¨μˆ˜λ₯Ό λ§Œλ“  λ‹€μŒ 3개의 λ‹€λ₯Έ 인수 μ„ΈνŠΈλ‘œ μ—°μ†ν•΄μ„œ 3번 ν˜ΈμΆœν•˜λ©΄ (v1.1.7 ν˜„μž¬) λž˜ν•‘λœ νŽ˜μ΄λ‘œλ“œ ν•¨μˆ˜κ°€ μ΅œμ’…μ μœΌλ‘œ λ‹€μŒμ—μ„œ μ§€μ •ν•œ 인수둜 ν˜ΈμΆœλ©λ‹ˆλ‹€. μ„Έ 번째 호좜 - 첫 번째 및 두 번째 μΈμˆ˜κ°€ μ‚­μ œλ©λ‹ˆλ‹€.

이것은 μ’…μ’… μœ νš¨ν•˜μ§€λ§Œ(그리고 일반적으둜 ν‚€ λ””λ°”μš΄μ‹±μ΄ μˆ˜ν–‰ν•˜λŠ” μž‘μ—…, λ”°λΌμ„œ 합리적인 κΈ°λ³Έκ°’) λ‚˜λŠ” λ””λ°”μš΄μŠ€λ₯Ό μ‚¬μš©ν•˜μ—¬ 인수λ₯Ό λˆ„μ ν•˜κ³  μ‹Άμ–΄ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ ν•œ λ²ˆμ— μ—¬λŸ¬ ν‚€λ₯Ό κ°€μ Έμ˜¬ 수 μžˆλŠ” AJAX 호좜이 μžˆμœΌλ―€λ‘œ λ””λ°”μš΄μŠ€λ₯Ό μ‚¬μš©ν•˜μ—¬ λ²„νΌλ§ν•©λ‹ˆλ‹€. ν‚€λ₯Ό μž μ‹œ λˆ„λ₯΄κ³  κ²°ν•©λœ μš”μ²­μ„ λ°œν–‰ν•˜μ‹­μ‹œμ˜€.

λ”°λΌμ„œ λ‚΄ μ œμ•ˆμ€ λ””λ°”μš΄μŠ€κ°€ 2개의 인수둜 호좜될 선택적 μ„Έ 번째 "κ²°ν•©" 인수λ₯Ό μ·¨ν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

  • 첫 λ²ˆμ§ΈλŠ” μ§€κΈˆκΉŒμ§€ μΆ•μ λœ 인수 λͺ©λ‘μž…λ‹ˆλ‹€(μ •μ˜λ˜μ§€ μ•Šμ•˜μ„ 수 있음 - 첫 번째 호좜 μ‹œ λͺ©λ‘ μ—†μŒ)
  • 두 λ²ˆμ§ΈλŠ” μ΅œμ‹  ν˜ΈμΆœμ— λŒ€ν•œ 인수 λͺ©λ‘(빈 λͺ©λ‘μΌ 수 있음)
    λˆ„μ λœ 인수의 μƒˆ λͺ©λ‘μ„ λ°˜ν™˜ν•©λ‹ˆλ‹€. νŽ˜μ΄λ‘œλ“œ ν•¨μˆ˜κ°€ 호좜되면 λˆ„μ λœ 인수 λͺ©λ‘μ΄ μ§€μ›Œμ§‘λ‹ˆλ‹€.

κ²°ν•© λ§€κ°œλ³€μˆ˜μ— 값이 μ „λ‹¬λ˜μ§€ μ•ŠμœΌλ©΄ κΈ°λ³Έ 결합이 κΈ°μ‘΄ λ™μž‘μ„ μœ μ§€ν•©λ‹ˆλ‹€.
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]둜 console.logλ₯Ό ν˜ΈμΆœν•©λ‹ˆλ‹€.

λͺ¨λ“  11 λŒ“κΈ€

λ‚΄ μžμ‹ μ˜ μ œμ•ˆμ— λŒ€ν•΄ μ–ΈκΈ‰ν•˜μžλ©΄, Combine() ν˜ΈμΆœμ€ νŽ˜μ΄λ‘œλ“œ ν•¨μˆ˜μ™€ λ™μΌν•œ μ»¨ν…μŠ€νŠΈλ₯Ό 지정해야 ν•˜λ―€λ‘œ

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]둜 console.logλ₯Ό ν˜ΈμΆœν•©λ‹ˆλ‹€.

@schmerg β€” 이것은 맀우 μœ μš©ν•΄ λ³΄μž…λ‹ˆλ‹€. MIT λΌμ΄μ„ μŠ€μ— 따라 ν•΄λ‹Ή μ½”λ“œμ— λΌμ΄μ„ μŠ€λ₯Ό λΆ€μ—¬ν•˜μ‹œκ² μŠ΅λ‹ˆκΉŒ? ("예"둜 μΆ©λΆ„ν•©λ‹ˆλ‹€!)

@markjaquith 물둠이죠 - κ·Έλ ‡μŠ΅λ‹ˆλ‹€. 닀행이닀...

λˆ„κ΅°κ°€κ°€ μ™€μ„œ μœ„μ˜ μ΅œμ‹  js 버전을 μ—…λ°μ΄νŠΈ/μ„€λͺ…ν•˜κ³  μ‹Άλ‹€λ©΄:

_.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();
    };
  },
});

@kmanislands μ•ˆλ…•ν•˜μ„Έμš”, κ·€ν•˜μ˜ 버전은 wrapper() allArgs λ₯Ό μž¬μ„€μ •ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ func() 에 λŒ€ν•œ 후속 ν˜ΈμΆœμ€ ν˜„μž¬ 배치뿐만 μ•„λ‹ˆλΌ args의 역사적 λ°°μΉ˜λ„ κ°€μ Έμ˜΅λ‹ˆλ‹€.

λ‹€μŒκ³Ό κ°™μ•„μ•Ό ν•©λ‹ˆλ‹€.

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

@markjaquith +1

λ˜ν•œ func( args ) λŠ” func.apply(context, args); λ₯Ό μ‚¬μš©ν•˜λŠ” μ›λž˜ 버전과 λ‹€λ¦…λ‹ˆλ‹€.
μ „μžμ˜ 경우 args λŠ” λŒ€μƒ func() μ—μ„œ κ·ΈλŒ€λ‘œ μ‚¬μš©λ˜λŠ” 반면, λ‚˜μ€‘ _(μ›λž˜ μ½”λ“œ)_μ—μ„œλŠ” 일반 ν•¨μˆ˜μ—μ„œ arguments 쀑 ν•˜λ‚˜λ₯Ό μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€. λ˜λŠ” es6 팻 ν™”μ‚΄ν‘œ ν•¨μˆ˜μ—μ„œ ( ...args ) .

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰