javascript - angular watchers 和 event listeners 以什么顺序执行?

标签 javascript angularjs angularjs-digest

如果先更改作用域属性,然后再广播事件,那么相应的观察者回调和事件监听者回调是否总是以相同的顺序执行?例如:

$scope.foo = 3;
$scope.$broadcast('bar');

和其他地方:

$scope.$watch('foo', function fn1(){...});
$scope.$on('bar', function fn2(){...});

fn1 是否总是在 fn2 之前执行,反之亦然,或者是否可以不依赖该顺序?请引用来源,最好是官方 Angular 文档。

以防万一:假设 $scope.foo= 和 $broadcast 发生在由 ng-click(即用户交互)调用的函数中

[旁白] 抱歉,问题标题草率 - 如果您有更好的名称,请重命名。

最佳答案

要了解发生了什么,您需要了解 Angular 的 $digest周期和事件 $emit and $broadcast功能。

根据一些研究,我还了解到 Angular does not use any kind of polling mechanism to periodically check for model changes .这在 Angular 文档中没有解释,但可以测试(参见 this answer to a similar question )。

将所有这些放在一起,我写了 a simple experiment并得出结论,您可以依赖首先运行的事件处理程序,然后再运行您的监视功能。这是有道理的,因为在摘要循环期间可以连续多次调用 watch 函数。

下面的代码...

template.html

<div ng-app="myApp">
  <div watch-foo ng-controller="FooController">
    <button ng-click="changeFoo()">
      Change
    </button>
  </div>
</div>

script.js

angular.module('myApp', [])
  .directive('watchFoo', watchFooDirective)
  .controller('FooController', FooController);

function watchFooDirective($rootScope) {
  return function postLink(scope) {
    scope.$watch(function () {
        return scope.foo;
    }, function (value) {
        console.log('scope.$watch A');
    });
    scope.$on('foo', function (value) {
        console.log('scope.$on A');
    });
    $rootScope.$on('foo', function (value) {
        console.log('$rootScope.$on A');
    });
    $rootScope.$on('foo', function (value) {
        console.log('$rootScope.$on B');
    });
    scope.$on('foo', function (value) {
        console.log('scope.$on B');
    });
    scope.$watch(function () {
        return scope.foo;
    }, function (value) {
        console.log('scope.$watch B');
    });
  };
}

function FooController($scope) {
  $scope.foo = 'foo';
  $scope.changeFoo = function() {
    $scope.foo = 'bar';
    $scope.$emit('foo');
  };
}

...单击“更改”按钮时在控制台中产生以下结果:

scope.$on A
scope.$on B
$rootScope.$on A
$rootScope.$on B
scope.$watch A
scope.$watch B

更新

这是另一个测试,说明在摘要循环中两次调用监视回调,但没有第二次调用事件处理程序:https://jsfiddle.net/sscovil/ucb17tLa/

第三个测试在监视函数中发出一个事件,然后更新被监视的值:https://jsfiddle.net/sscovil/sx01zv3v/

在所有情况下,您都可以依赖在监视函数之前调用的事件监听器。

关于javascript - angular watchers 和 event listeners 以什么顺序执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34519047/

相关文章:

javascript - React useState 钩子(Hook),用函数调用 setState

javascript - 无法使用 chrome.management API

javascript - 单选按钮 angularjs 不起作用

javascript - 使用 ng-class 显示一些文本

javascript - angularjs 中的变量未更新

javascript - Angular.js 深度对象解析

按钮单击事件上的 JavaScript 函数在 WaveMaker 中不起作用

javascript - 如何根据窗口宽度使用 JavaScript 更改图像元素类?

javascript - 如何在另一个完整页面上显示在 iframe 中打开的弹出窗口

javascript - ng-repeat 中的 Angularjs 函数调用次数过多