2015-02-26 2 views

ответ

2

Я понимаю, что это выглядит примерно так:

function debounce(duration) { 
    var _timer = null; 
    var toCall = []; 

    function dispatch() { 
     _timer = null; 
     toCall.forEach(function(opts) { 
      if (opts.shouldCall) { 
       opts.fn.apply(undefined, opts.args); 
      } 
      opts.shouldCall = false; 
     }); 
    } 

    return function debounce(fn) { 
     var myAction = {fn: fn, args: [], shouldCall: false}; 
     toCall.push(myAction); 

     return function() { 
      myAction.shouldCall = true; 
      myAction.args = Array.prototype.slice.call(arguments); 

      clearTimeout(_timer); 
      _timer = setTimeout(dispatch, duration); 
     }; 
    }; 
} 

Это выглядит довольно сложно, но все это на самом деле представляет собой замыкающий только общий дребезг. Множественные функции дебютируют на одном таймере, и все вызываются в одном тике. Самые последние аргументы сохраняются (не нужны в этом конкретном случае, но это не вызовет проблем).

Мы создаем один из них для всех (не каждый) наших магазинов. Продолжительность в основном произвольная, но достаточно длинная, чтобы позволить браузеру отображать фрейм между нами, делая нашу логику обновления магазина, и обновление пользовательского интерфейса, которое может заставить прокрутку чувствовать себя более отзывчивым.

var storeDebounce = debouncer(20); 

В наших магазинах, вместо этого:

emitChange: function() { 
    this.emit(CHANGE_EVENT); 
    }, 

Мы делаем это:

emitChange: storeDebounce(function() { 
    this.emit(CHANGE_EVENT); 
    }.bind(this)), 

Теперь, если магазин или магазины обновляются несколько раз в том же клещ, или короткий преемственность (часто происходит с обещаниями или другим гарантированным асинхронным кодом), мы будем выпустить только одно событие изменения для каждого затронутого хранилища.

отказ от ответственности: не тестировалось

+0

Можете ли вы пролить свет немного на 'Мы создаем один из них для всех (не каждый) нашей stores'? – message

+0

@message, иначе у вас будет разница setTimeout для события изменения каждого магазина, и все они будут отправлены друг за другом, что может привести к тому, что некоторые компоненты будут иметь устаревшие данные и даже ошибки, которые должны быть невозможны. Важным моментом в оптимизации является то, что вы не нарушаете что-либо в соответствии с лучшими практиками (# 2 не нарушает ничего, но иногда это допускается). – FakeRainBrigand

+0

Итак, вам нужно иметь только один 'emitChange: storeDebounce' для всех магазинов ?! Где это должно быть определено, чтобы повлиять на все магазины? Можете ли вы добавить несколько примеров, используя 2 магазина и общий emitchange (если он работает так, как я думаю)? – message