[AngularJS面面观] 5. scope中的两个异步方法 - $applyAsync以及$evalAsync

本文详细分析了AngularJS中$applyAsync和$evalAsync两个异步方法的实现原理和使用场景,探讨了它们在digest循环中的作用,以及如何优化应用性能,特别提到了在处理并发HTTP请求时的使用策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Angular中digest循环的主干是对于watchers的若干次遍历,直到整个scope中的数据”稳定”下来,这部分实现在这篇文章中已经进行了详尽的介绍。相关的一些细节优化也在这篇文章中进行了分析。

除了主干的内容,digest循环的内容其实还包括几个比较有趣的部分,比如这一节我们即将分析的$evalAsync以及$applyAsync,下面我们就来通过相关源代码来分析一下:

$digest: function() {
   
  var watch, value, last, fn, get,
      watchers,
      length,
      dirty, ttl = TTL,
      next, current, target = this,
      watchLog = [],
      logIdx, logMsg, asyncTask;

  beginPhase('$digest');
  // Check for changes to browser url that happened in sync before the call to $digest
  $browser.$$checkUrlChange();

  if (this === $rootScope && applyAsyncId !== null) {
    // If this is the root scope, and $applyAsync has scheduled a deferred $apply(), then
    // cancel the scheduled $apply and flush the queue of expressions to be evaluated.
    $browser.defer.cancel(applyAsyncId);
    flushApplyAsync();
  }

  lastDirtyWatch = null;

  do { // "while dirty" loop
    dirty = false;
    current = target;

    while (asyncQueue.length) {
      try {
        asyncTask = asyncQueue.shift();
        asyncTask.scope.$eval(asyncTask.expression, asyncTask.locals);
      } catch (e) {
        $exceptionHandler(e);
      }
      lastDirtyWatch = null;
    }

    traverseScopesLoop:
    do { // "traverse the scopes" loop
      if ((watchers = current.$$watchers)) {
        // process our watches
        length = watchers.length;
        while (length--) {
          try {
            watch = watchers[length];
            // Most common watches are on primitives, in which case we can short
            // circuit it with === operator, only when === fails do we use .equals
            if (watch) {
              get = watch.get;
              if ((value = get(current)) !== (last = watch.last) &&
                  !(watch.eq
                      ? equals(value, last)
                      : (typeof value === 'number' && typeof last === 'number'
                         && isNaN(value) && isNaN(last)))) {
                dirty = true;
                lastDirtyWatch = watch;
                watch.last = watch.eq ? copy(value, null) : value;
                fn = watch.fn;
                fn(value, ((last === initWatchVal) ? value : last), current);
                if (ttl < 5) {
                  logIdx = 4 - ttl;
                  if (!watchLog[logIdx]) watchLog[logIdx] = [];
                  watchLog[logIdx].push({
          
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值