2019独角兽企业重金招聘Python工程师标准>>>

 $digest: function() {var watch, value, last,watchers,asyncQueue = this.$$asyncQueue,postDigestQueue = this.$$postDigestQueue,length,dirty, ttl = TTL,next, current, target = this,watchLog = [],logIdx, logMsg, asyncTask;//beginPhase和clearPhase 用来进行状态管理beginPhase('$digest');lastDirtyWatch = null;do { // "while dirty" loopdirty = false;current = target;while(asyncQueue.length) {try {asyncTask = asyncQueue.shift();asyncTask.scope.$eval(asyncTask.expression);} catch (e) {clearPhase();$exceptionHandler(e);}lastDirtyWatch = null;}traverseScopesLoop:do { // "traverse the scopes" loopif ((watchers = current.$$watchers)) {// process our watcheslength = 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 .equalsif (watch) {if ((value = watch.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) : value;watch.fn(value, ((last === initWatchVal) ? value : last), current);if (ttl < 5) {logIdx = 4 - ttl;if (!watchLog[logIdx]) watchLog[logIdx] = [];logMsg = (isFunction(watch.exp))? 'fn: ' + (watch.exp.name || watch.exp.toString()): watch.exp;logMsg += '; newVal: ' + toJson(value) + '; oldVal: ' + toJson(last);watchLog[logIdx].push(logMsg);}} else if (watch === lastDirtyWatch) {// If the most recently dirty watcher is now clean, short circuit since the remaining watchers// have already been tested.dirty = false;break traverseScopesLoop;}}} catch (e) {clearPhase();$exceptionHandler(e);}}}// Insanity Warning: scope depth-first traversal// yes, this code is a bit crazy, but it works and we have tests to prove it!// this piece should be kept in sync with the traversal in $broadcastif (!(next = (current.$$childHead ||(current !== target && current.$$nextSibling)))) {while(current !== target && !(next = current.$$nextSibling)) {current = current.$parent;}}} while ((current = next));// `break traverseScopesLoop;` takes us to hereif((dirty || asyncQueue.length) && !(ttl--)) {clearPhase();throw $rootScopeMinErr('infdig','{0} $digest() iterations reached. Aborting!\n' +'Watchers fired in the last 5 iterations: {1}',TTL, toJson(watchLog));}} while (dirty || asyncQueue.length);clearPhase();while(postDigestQueue.length) {try {postDigestQueue.shift()();} catch (e) {$exceptionHandler(e);}}},$destroy: function() {// we can't destroy the root scope or a scope that has been already destroyedif (this.$$destroyed) return;var parent = this.$parent;this.$broadcast('$destroy');this.$$destroyed = true;if (this === $rootScope) return;forEach(this.$$listenerCount, bind(null, decrementListenerCount, this));if (parent.$$childHead == this) parent.$$childHead = this.$$nextSibling;if (parent.$$childTail == this) parent.$$childTail = this.$$prevSibling;if (this.$$prevSibling) this.$$prevSibling.$$nextSibling = this.$$nextSibling;if (this.$$nextSibling) this.$$nextSibling.$$prevSibling = this.$$prevSibling;// This is bogus code that works around Chrome's GC leak// see: https://github.com/angular/angular.js/issues/1313#issuecomment-10378451this.$parent = this.$$nextSibling = this.$$prevSibling = this.$$childHead =this.$$childTail = null;},$eval: function(expr, locals) {return $parse(expr)(this, locals);},$evalAsync: function(expr) {// if we are outside of an $digest loop and this is the first time we are scheduling async// task also schedule async auto-flushif (!$rootScope.$$phase && !$rootScope.$$asyncQueue.length) {//$browser.defer 把这个看做setTimout$browser.defer(function() {if ($rootScope.$$asyncQueue.length) {$rootScope.$digest();}});}this.$$asyncQueue.push({scope: this, expression: expr});},$$postDigest : function(fn) {this.$$postDigestQueue.push(fn);},//执行完expr,会$digest一遍。//这样做得好处是,expr的执行不会影响到$digest$apply: function(expr) {try {beginPhase('$apply');return this.$eval(expr);} catch (e) {$exceptionHandler(e);} finally {clearPhase();try {$rootScope.$digest();} catch (e) {$exceptionHandler(e);throw e;}}},//$broadcast,$on,$emit 省略掉//$broadcast,$emit 的作用就是,沿着Scope的关系上下注册的事件,事件的格式要注意一下//{//          name: name,//          targetScope: scope,//          stopPropagation: function() {stopPropagation = true;},//          preventDefault: function() {//            event.defaultPrevented = true;//          },//          defaultPrevented: false//        },这些可以用来阻止事件的冒泡//$on的事件存储在每个$scope中的 $$listeners对象中,可以多次$on同一个namevar $rootScope = new Scope();return $rootScope;//类似于java中的线程锁的概念function beginPhase(phase) {if ($rootScope.$$phase) {throw $rootScopeMinErr('inprog', '{0} already in progress', $rootScope.$$phase);}$rootScope.$$phase = phase;}function clearPhase() {$rootScope.$$phase = null;}}

看到这里,可以看出angularJS以响应status变化的模式(具体的学术性名称忘掉了)来做监控,在js中,这会导致随着status的增多,监控会越来越慢的问题。或许在js中,也只能如此的做监控了。如果读者知道有做js函数式响应监控的框架或demo,麻烦留言一下。嘿嘿。

转载于:https://my.oschina.net/myprogworld/blog/223524

AngularJS-源码阅读(八.二)相关推荐

  1. mybatis源码阅读(八) ---Interceptor了解一下

    转载自  mybatis源码阅读(八) ---Interceptor了解一下 1 Intercetor MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用.默认情况下,MyBatis允许 ...

  2. Alibaba Druid 源码阅读(二) 数据库连接池实现初步探索

    Alibaba Druid 源码阅读(二) 数据库连接池实现初步探索 简介 在上篇文章中,了解了连接池的应用场景和本地运行了示例,本篇文章中,我们尝试来探索下Alibaba Druid数据库连接池的整 ...

  3. Soul 网关源码阅读(二)代码初步运行

    Soul 源码阅读(二)代码初步运行 简介     基于上篇:Soul 源码阅读(一) 概览,这部分跑一下Soul网关的示例 过程记录     现在我们可以根据地图,稍微探索一下周边,摸一摸      ...

  4. Mybatis源码阅读之二——模板方法模式与Executor

    [系列目录] Mybatis源码阅读之一--工厂模式与SqlSessionFactory 文章目录 一. 模板方法模式 二. 同步回调与匿名函数 三. Executor BaseExecutor与其子 ...

  5. gin context和官方context_gin 源码阅读(二) 路由和路由组

    " 上一篇讲的是gin 框架的启动原理,今天来讲一下 gin 路由的实现. 1 用法 还是老样子,先从使用方式开始: func main() { r := gin.Default() r.G ...

  6. Rpc框架dubbo-client(v2.6.3) 源码阅读(二)

    接上一篇 dubbo-server 之后,再来看一下 dubbo-client 是如何工作的. dubbo提供者服务示例, 其结构是这样的! dubbo://192.168.11.6:20880/co ...

  7. Lidar_imu自动标定源码阅读(二)——calibration部分

    源码阅读,能力有限,如有某处理解错误,请指出,谢谢. Lidar_parser_base.h:激光雷达分析器基础 #pragma once#include <pcl/point_cloud.h& ...

  8. angularjs源码阅读-1-模块加载器

    angularjs源码-setupModuleLoader 背景和开始 publishExternalAPI引入setupModuleLoader setupModuleLoader下面的逻辑 ens ...

  9. Kafka源码阅读-Controller(二)管理brokers

    上一篇kafka源码(一)correspond to/explain Kafka设计解析(二) 中的3.2.3.3.以前一直用kafka 0.8.2.x,那时候redis开始风靡,hadoop方兴未艾 ...

  10. werkzeug源码阅读笔记(二) 下

    wsgi.py----第二部分 pop_path_info()函数 先测试一下这个函数的作用: >>> from werkzeug.wsgi import pop_path_info ...

最新文章

  1. C#设计模式(23种设计模式)
  2. Java01-day01【发展史、跨平台原理、JRE和JDK、常用DOS命令、关键字、常量、数据类型、变量使用的注意事项、标识符、类型转换】
  3. java上传文件到ftp_java实现文件上传下载至ftp服务器
  4. 博客园贵团队可以给个解释么?
  5. mysql 查看索引命中_请问下如何在Mysql中where与orderBy后在命中索引?
  6. java怎么获取ie浏览器的cookie,IE8 浏览器Cookie的处理
  7. 自学考试c语言真题,自学考试《C语言程序设计》复习试题及答案
  8. 关于matlab中get和set的用法
  9. 淘宝数据分析工具汇总
  10. Javascript:Ajax讲解
  11. 数据库悲观锁和乐观锁
  12. AifbdScore智能AI曲谱乐谱播放识别SDK midi曲谱 应用开发 五线谱 六线谱 四线谱播放
  13. https://mp.csdn.net/
  14. 异数OS 星星之火(一)-- 异数OS-织梦师云 用户使用手册
  15. 【Codecs系列】CABAC熵编码详解
  16. 组队开发最后冲刺周第三次会议
  17. 前缀编码是什么?哈夫曼编码是什么?
  18. omf多路径 oracle_ORACLE OMF
  19. C语言输出国际象棋的棋盘
  20. python爬取高匿代理IP(再也不用担心会进小黑屋了)

热门文章

  1. spring security 的 logout 功能
  2. 雷林鹏分享:PHP 表单验证
  3. Ubuntu 16.04安装 Nmap 6.46.1
  4. Rainbond 5.1.3 发布,快速部署和运维 Spring Cloud 集群
  5. 一步步实现 Redis 搜索引擎 1
  6. java大神养成计划
  7. mysql 相关记录
  8. 分布式平台下的HS(High-Security) --对称加密
  9. alluxio2.0特性-预览
  10. scrapy爬虫框架入门实战