При работе с функциями, которые могут вызываться большое количество раз в течение короткого промежутка времени, может возникнуть ситуация, когда время выполнения такой функции (например, асинхронный запрос на сервер) в несколько раз превышает интервал между её вызовами. Такую ситуацию можно исправить, ограничив количество запусков в течение какого-то времени.
Фреймворк Underscore предоставляет два вспомогательных метода для этих целей.
function debounce(func, wait, immediate) {
var timeout;
return function () {
var context = this, args = arguments;
var later = function () {
timeout = null;
if (!immediate) {
func.apply(context, args);
}
};
if (immediate && !timeout) {
func.apply(context, args);
}
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
Метод debounce
возвращает функцию, которая будет выполнена только 1 раз через заданный промежуток времени, если в течение этого промежутка не было других вызовов. Если передан параметр
immediate
, то выполнение произойдет в начале интервала, а не в конце.
$(window).on("resize", debounce(function () {
console.log("resize event");
}, 1000));
Пока пользователь будет менять окно в размерах, никаких сообщений в консоли не будет. Оно появится через 1 секунду после того, как он остановится.
$(window).on("resize", debounce(function () {
console.log("resize event");
}, 1000, true));
Сообщение появится сразу, как только пользователь начнет менять размеры окна. Следующее сообщение будет выведено, если промежуток между действиями пользователя будет более 1 секунды.
function throttle(func, wait) {
var context, args, timeout, throttling, more, result;
var whenDone = debounce(function () {
more = throttling = false;
}, wait);
return function () {
context = this;
args = arguments;
var later = function () {
timeout = null;
if (more) {
func.apply(context, args);
}
whenDone();
};
if (!timeout) {
timeout = setTimeout(later, wait);
}
if (throttling) {
more = true;
} else {
result = func.apply(context, args);
}
whenDone();
throttling = true;
return result;
};
}
Метод throttle
возвращает функцию, которая выполнит самый последний вызов в течение указанного промежутка времени.
$(window).on("resize", throttle(function () {
console.log("resize event");
}, 1000));
При изменении размеров окна сообщение будет выводиться в консоль ровно 1 раз в секунду.