`
leeqq
  • 浏览: 139335 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

angular的$timeout和window.setTimeout的区别

阅读更多

这个问题也是前段时间面试的时候面试官问的,当时也只是略知一二,后来回来后查看的源码,才搞清楚

总结起来有以下几点:

1. 在$timeout中传入的函数会被包含在try...catch中,并且在异常时将异常交给$exceptionHandler

2. window.setTimeout返回的是数字id,可以通过window.clearTimeout(id)取消,而$timeout返回的是promise对象,要取消要用$timeout.cancel(返回的promise对象)

3. $timeout传入的function会更新作用域内的数据绑定,也就是说在function中对$scope的修改会触发更新,而window.setTimeout中对$scope的修改不会触发更新。当然$timeout有第三个参数,默认为true,如果传入false,则不会更新当前作用域的数据绑定

 

当然$timeout的实现仍然是调用原生的window.setTimeout。那么是怎么实现的呢。看看源码就知道了。

function timeout(fn, delay, invokeApply) {
  var skipApply = (isDefined(invokeApply) && !invokeApply),
      deferred = (skipApply ? $$q : $q).defer(),
      //要返回的prosemise对象
      promise = deferred.promise,
      timeoutId;

  timeoutId = $browser.defer(function() {
    try {
      //这里调用了fn(),并且把返回值作为resolve的参数,如果对$timeout返回的promise对象调用的then方法,这里fn的返回值就可以用到了
      deferred.resolve(fn());
    } catch(e) {
      deferred.reject(e);
      $exceptionHandler(e);
    }
    finally {
      delete deferreds[promise.$$timeoutId];
    }
    //通过第三个参数来确定是否要执行$apply触发更新
    if (!skipApply) $rootScope.$apply();
  }, delay);
  //在timeoutId挂在promise对象上
  promise.$$timeoutId = timeoutId;
  deferreds[timeoutId] = deferred;
  //返回的promise对象
  return promise;
}

 $browser.defer方法如下

self.defer = function(fn, delay) {
    var timeoutId;
    outstandingRequestCount++;
    //此处调用了原生的setTimeout并返回数字id
    timeoutId = setTimeout(function() {
        delete pendingDeferIds[timeoutId];
        completeOutstandingRequest(fn);
    }, delay || 0);
    pendingDeferIds[timeoutId] = true;
    return timeoutId;
};

 在实际应用时如下

 

var returnedPromise = $timeout(function(){return 'value';}, 2000);

这里可以对returnedPromise调用then方法或者finally等方法

returnedPromise.then(resolveFun, rejectFun, progressFun)

这时到时间后resolveFun这些方法也要执行

分享到:
评论

相关推荐

    angularjs之$timeout指令详解

    angular.js的$timeout指令对window.setTimeout做了一个封装,它的返回值是一个promise对象.当定义的时间到了以后,这个promise对象就会被resolve,回调函数就会被执行. 如果需要取消一个timeout,调用$timeout.cancel...

    AngularJs定时器$interval 和 $timeout详解

    最后,虽然$interval和$timeout服务的使用与JavaScript原生的setInterval和setTimeout非常相似,但它们具有AngularJS的特殊处理,比如在AngularJS的脏值检查机制内,以及它们返回promise对象的特性,这使得它们更加...

    AngularJS入门教程之服务(Service)

    $timeout服务提供了与JavaScript原生window.setTimeout功能相似的功能。在AngularJS中,$timeout服务的好处是它能够自动处理作用域(scope)的脏检查。这意味着当你设置了一个延时任务后,一旦返回的promise被解决,...

    详解AngularJS脏检查机制及$timeout的妙用

    $timeout是AngularJS提供的一个封装了window.setTimeout的特殊服务。它的妙用在于可以在延迟任务中修改被绑定到界面的变量。window.setTimeout本身不会触发脏检查机制来更新UI界面,因此如果直接使用window....

    javascript

    5. **异步编程**:回调函数、事件循环、Promise(then、catch、finally)、async/await、Timeout和Interval。 6. **DOM操作**:获取元素(getElementById、getElementsByClassName、querySelectorAll等)、修改元素...

    AngularJs定制样式插入到ueditor中的问题小结

    由于ueditor的初始化需要DOM元素加载完成,而AngularJS的`ng-repeat`等指令可能在DOM加载后才执行,因此可能需要使用`$timeout`或`$apply`来确保在正确的时机操作编辑器实例。 总之,AngularJS与ueditor的集成涉及...

Global site tag (gtag.js) - Google Analytics