在这个用例中,$ interval和$ timeout之间是否有真正的区别?

时间:2014-08-10 18:02:05

标签: javascript angularjs

之间存在真正的区别:

$interval(function () {
  doSomething();
}, 250, 1, true);

$timeout(function () {
  doSomething();
}, 250);
  • 两者都归还承诺
  • 两者都执行doSomething()一次。
  • 两者都触发了摘要周期。

我唯一可能注意到的差异是,如果我使用false作为$interval的最后一个参数,我可以绕过摘要周期。

2 个答案:

答案 0 :(得分:1)

让我们做一些代码分析

超时

function timeout(fn, delay, invokeApply) {
  var deferred = $q.defer(),
      promise = deferred.promise,
      skipApply = (isDefined(invokeApply) && !invokeApply),
      timeoutId;

  timeoutId = $browser.defer(function() {
    try {
      deferred.resolve(fn());
    } catch(e) {
      deferred.reject(e);
      $exceptionHandler(e);
    }
    finally {
      delete deferreds[promise.$$timeoutId];
    }

    if (!skipApply) $rootScope.$apply();
  }, delay);

  promise.$$timeoutId = timeoutId;
  deferreds[timeoutId] = deferred;

  return promise;
}

间隔

function interval(fn, delay, count, invokeApply) {
  var setInterval = $window.setInterval,
      clearInterval = $window.clearInterval,
      deferred = $q.defer(),
      promise = deferred.promise,
      iteration = 0,
      skipApply = (isDefined(invokeApply) && !invokeApply);

  count = isDefined(count) ? count : 0;

  promise.then(null, null, fn);

  promise.$$intervalId = setInterval(function tick() {
    deferred.notify(iteration++);

    if (count > 0 && iteration >= count) {
      deferred.resolve(iteration);
      clearInterval(promise.$$intervalId);
      delete intervals[promise.$$intervalId];
    }

    if (!skipApply) $rootScope.$apply();

  }, delay);

  intervals[promise.$$intervalId] = deferred;

  return promise;
}

最后的差异并非如此,因为两种方法都实现了if (!skipApply) $rootScope.$apply(); 没有区别

答案 1 :(得分:0)

存在差异,但问题中提到的各点都没有。也就是说,$timeout的promise解析为延迟函数的返回值,如果函数抛出异常,则拒绝该异常。 $interval的承诺传递notify个事件,如果指定了最大迭代次数并最终达到,则最终使用当前迭代计数解析。另外,传递给$interval的函数接收当前迭代作为参数,而Angular对函数内部抛出的异常不做任何事。

考虑the following code

$timeout(function() {
  return "first";
}, 100).then(function(value) {
  // logs "Timeout resolved to: first"
  console.log("Timeout resolved to: " + value);
});

$interval(function(iteration) {
  // logs 0, 1, 2, 3, and 4
  console.log(iteration);
  return "second";
}, 20, 5).then(function(value) {
  // logs "Interval resolved to: 5"
  console.log("Interval resolved to: " + value);
});