Однократный вызов функции с таймаутом

Бывает нужно подписаться на какое-то событие, но нет уверенности, что оно вообще может наступить. Можно условиться о неком интервале, в течение которого мы ожидаем это событие.


/**
 * @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 или другой библиотеки, реализующей промисы.