一尘不染

Angular JS:链接承诺和摘要周期

angularjs

注意: 小提琴使用的是Angular的旧版本,并且不再起作用,因为从1.2版开始,Angular模板引擎无法透明地处理Promise。

我正在研究链接诺言以填充我的范围,然后让范围自动更新dom。

但是,我遇到了问题。如果我在已经解决的Promise上调用“
then”,它将创建一个新的Promise(它将异步但几乎立即调用成功函数)。我认为问题在于,在调用成功函数时,我们已经离开了摘要周期,因此dom永远不会更新。

这是代码:

<div ng-controller="MyCtrl">
    Hello, {{name}}! <br/>
    {{name2}}<br/>
    <button ng-click="go()">Clickme</button><br/>
    {{name3}}
</div>

var myApp = angular.module('myApp',[]);

function MyCtrl($scope, $q) {
    var data = $q.defer();    
    setTimeout(function() {$scope.$apply(data.resolve("Some Data"))}, 2000);
    var p = data.promise;

    $scope.name = p.then(angular.uppercase);
    $scope.name2 = p.then(function(x) { return "Hi "+x;});
    $scope.go = function() {
            $scope.name3 = p.then(function(x) { 
                // uncomment this to make it work:
                //$scope.$apply();
                return "Finally: "+x;
            });
    };
 }

http://jsfiddle.net/QZM4d/

有什么方法可以使此工作在我每次连锁承诺时都无需调用$ apply?


阅读 206

收藏
2020-07-04

共1个答案

一尘不染

注意 :小提琴使用的是Angular的旧版本,并且不再起作用,因为从1.2版本开始,Angular模板引擎无法透明地处理Promise。

要引用 @ pkozlowski.opensource:

在AngularJS中,承诺解析的结果在$ digest周期内异步传播。因此,仅在进入$ digest循环后才会调用then()注册的回调。

因此,单击该按钮时,我们处于摘要周期。then()创建了一个新的promise,但是then()的结果要到 下一个
摘要周期才会传播,该摘要周期永远不会到来(因为没有$ timeout或$ http或DOM事件来触发它)。如果您用ng-
click添加另一个不执行任何操作的按钮,然后单击该按钮,将导致摘要周期,您将看到结果:

<button ng-click="">Force digest by clicking me</button><br/>

这是一个小提琴

小提琴还使用$ timeout而不是setTimeout -则不需要$ apply()。

希望您何时需要使用$ apply清楚。有时您确实需要手动调用它。

2020-07-04