Недавний React.JS Conf имел панель Flux и Kyle Davis mentioned de-bounce calls на основе оптимизации цикла отправки. Может ли кто-нибудь привести некоторые примеры того, как это реализовать?Отказ от вызова на основе цикла отправки в React
ответ
Я понимаю, что это выглядит примерно так:
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)),
Теперь, если магазин или магазины обновляются несколько раз в том же клещ, или короткий преемственность (часто происходит с обещаниями или другим гарантированным асинхронным кодом), мы будем выпустить только одно событие изменения для каждого затронутого хранилища.
отказ от ответственности: не тестировалось
Можете ли вы пролить свет немного на 'Мы создаем один из них для всех (не каждый) нашей stores'? – message
@message, иначе у вас будет разница setTimeout для события изменения каждого магазина, и все они будут отправлены друг за другом, что может привести к тому, что некоторые компоненты будут иметь устаревшие данные и даже ошибки, которые должны быть невозможны. Важным моментом в оптимизации является то, что вы не нарушаете что-либо в соответствии с лучшими практиками (# 2 не нарушает ничего, но иногда это допускается). – FakeRainBrigand
Итак, вам нужно иметь только один 'emitChange: storeDebounce' для всех магазинов ?! Где это должно быть определено, чтобы повлиять на все магазины? Можете ли вы добавить несколько примеров, используя 2 магазина и общий emitchange (если он работает так, как я думаю)? – message