前言
前端开发中常常需要监听某些数据的变化来更新页面,其中 AngularJS 1.x 中的 $watch
和 RxJS 中的 Observable 都是比较常用的技术,本文将对两种技术的使用场景、优缺点做详细的比较并给出示例代码,帮助读者选择合适的方式。
$watch
在 AngularJS 1.x 中,$watch
是用来监听一个 AngularJS 模型对象的变化,一旦对象有变化,就对应执行某个方法。例如以下代码:
$scope.$watch('name', function (newValue, oldValue) { console.log('name changed from ' + oldValue + ' to ' + newValue); });
这里用 $watch
监听了 $scope.name
,并且在变化时执行了回调函数,输出变化前后的值。$watch 和 AngularJS 提供的双向绑定是密切相关的,一旦 $scope.name
发生变化,绑定该数据的页面也会相应变化。
优点
- AngularJS 内置支持,使用较为方便;
- 在监听对象的属性时,可以使用点语法来监听对象内部属性的变化。
缺点
- 不支持 Promise 的异步处理;
- 多个 $watch 会影响性能;
- 可能会导致循环依赖的问题;
- 大规模数据监测性能问题。
Observable
Observable 是 RxJS 中的一个特性,可以用来监听数据流中的数据变化。在这里,数据流可以是一个数组、事件、HTTP 请求甚至是用户输入等等。
const source$ = of(1, 2, 3, 4, 5); const sub$ = source$.subscribe(val => console.log(val));
这里用 of
操作符创建了一个 Observable 对象,我们通过 subscribe
方法来监听其中的数据变化。
优点
- 接收的数据可以是异步的,支持 Promise 和其他异步请求;
- 执行效率高;
- 可以在多个流中复用代码。
缺点
- 学习成本较高;
- 需要手动管理订阅的生命周期。
比较
应用场景
AngularJS 中的 $watch
主要用于单向数据绑定,与 AngularJS 的双向数据绑定是结合使用的,适用于监听模型数据的变化。Observable 适用于监听各种异步数据流的变化。
学习成本
AngularJS 的 $watch
作为 AngularJS 的内置特性,使用起来较为简单。而 Observable 相比之下,需要更多的学习成本,不过 RxJSExt 库提供了许多工具来简化 Observable 的使用。
性能表现
$watch 监听的数据一旦开启较多,会严重影响运行效率。Observable 虽然在数据流多时表现良好,但同时需要考虑订阅的生命周期管理问题。
结论
选用何种方式主要依据业务需求和个人技术水平。对于单向数据绑定的场景,建议使用 $watch
;对于异步数据流监听的场景,建议使用 Observable。无论选哪种方式,都需要根据具体情况权衡其优、缺点来做出最终的决定。
示例代码
以下代码给出了一个使用 $watch 和 Observable 监听数组变化的示例:
// javascriptcn.com code example <div ng-controller="myController"> <p>使用 AngularJS $watch 来监听数组变化:</p> <ul> <li ng-repeat="item in arr">{{item}}</li> </ul> <p>使用 RxJS Observable 来监听数组变化:</p> <ul> <li *ngFor="let item of rxArr$ | async">{{item}}</li> </ul> </div>
// javascriptcn.com code example app.controller('myController', function($scope, $interval) { $scope.arr = [1, 2]; $interval(function () { // 在 $scope.arr 末尾添加一个随机数 $scope.arr.push(Math.floor(Math.random() * 10)); }, 1000); // 使用 $watch 监听数组变化 $scope.$watch('arr', function (newValue, oldValue) { console.log('arr changed from ' + oldValue + ' to ' + newValue); }, true); // 使用 RxJS Observable 监听数组变化 const rxArr$ = from($scope.arr); rxArr$.subscribe(() => { console.log('arr changed'); }); });
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/673496b50bc820c5824a0501