Бывает нужно подписаться на какое-то событие, но нет уверенности, что оно вообще может наступить. Можно условиться о неком интервале, в течение которого мы ожидаем это событие.
/**
* @param {Function} fn function which needs to be called only once
* @param {Number} timeout for external call
* @param {Object} [context]
* @returns {Function}
*/
function withTimeout(fn, timeout, context) {
var timerId, state = true;
function cb() {
if (timerId) {
clearTimeout(timerId);
timerId = null;
}
if (state) {
state = false;
fn.apply(context || window, arguments);
}
}
timerId = setTimeout(cb, timeout);
return cb;
}
С использованием промисов код получился бы чуть короче, но потребовал бы внешнюю зависимость в виде jQuery или другой библиотеки, реализующей промисы.