【问题标题】:Angular - how to chain a promise ($state.go function) to a timeout function?Angular - 如何将承诺($state.go 函数)链接到超时函数?
【发布时间】:2017-01-17 01:05:06
【问题描述】:

我正在尝试将一个承诺链接到我的“超时/打字机效果”函数,所以一旦他的函数完成,应该调用另一个函数,它是一个简单的 $state.go。我一直在研究和查看很多帖子,但无论我尝试什么都行不通——第一个函数永远不会被执行/或者可能被执行但太快以至于你什么都看不到——而只是第二个($state.go)函数是马上被处决。 任何想法将不胜感激。谢谢!

app.controller('homeCtrl', function($scope, $state, $q, $interval, $timeout) {
     function beginn() {
        var content = "helloo"
        $scope.typewriter = "";
        var i = 0;
        var timer = $interval(function() {
            if (i < content.length)
                $scope.typewriter += content[i];
            else {
                $interval.cancel(timer);
            }
            i++;

        }, 300)
    }

    function change() {
        $state.go('profile')
    }

    $q.when(beginn()).then(change);

});

html:

<p>{{typewriter}}</p>

【问题讨论】:

    标签: angularjs promise timeout angular-promise


    【解决方案1】:

    但是为什么你需要链接这两个承诺呢?您需要做的只是在角色完成推送时执行$state.go

    .controller('demoCtrl', ['$scope', '$state', '$interval', function($scope, $state, $interval) {
      var content = "helloo"
      $scope.typewriter = "";
      var i = 0;
      var timer = $interval(function() {
        if (i < content.length) {
          $scope.typewriter += content[i];
        } else {
          $state.go('home') // just go to the state directly
        }
        i++;
      }, 300)
    }])
    

    工作plnkr here

    编辑

    如果你想以你的(功能性)方式去做,你需要创建一个延迟承诺,然后在你完成推送字母时解决/拒绝它。

      function begin() {
        var deferred=  $q.defer();//create a deferred object using $q
    
        var content = "helloo";
        $scope.typewriter = "";
        var i = 0;
        var timer = $interval(function() {
          if (i < content.length) {
            $scope.typewriter += content[i];
          } else {
            deferred.resolve(); //resolve this when done
          }
          i++;
        }, 300);
        return deferred.promise; // return the promise of the deferred object
      }
    
      begin().then(()=>$state.go('home')) // call it as usual, but using .then
    

    工作plnkr here

    【讨论】:

    • 谢谢你-那个def。有道理:) 你还能告诉我我的承诺出了什么问题吗?不再是这个案子了,但我只想知道错误在哪里。谢谢!
    • @web2016 你需要在你的begin 函数中返回一个promise,并且你需要在它完成推送字母时解决它。我添加了一个编辑和一个有效的 plnkr。
    【解决方案2】:

    你的代码不工作的原因很简单,beginn函数在when中被调用时立即返回undefined(在$interval回调有机会执行之前。 由于您向$q.when 提供同步值(beginn() 返回的undefined),因此承诺将立即解决,因此then 块中的change 函数将在您提供给的回调之前立即调用$interval.

    如果你仍然认为你想使用 Promise api,那么你应该这样编写代码:

    app.controller('homeCtrl', function($scope, $state, $q, $interval, $timeout) {
     function beginn() {
        var content = "helloo"
        $scope.typewriter = "";
        var i = 0;
        return $q(function(resolve, reject) {
    
            var timer = $interval(function() {
                if (i < content.length)
                    $scope.typewriter += content[i];
                else {
                    $interval.cancel(timer);
                    resolve();
                }
                i++;
    
            }, 300);          
        });
    }
    
    function change() {
        $state.go('profile')
    }
    
    beginn().then(change);
    

    });

    看看beginn() 现在如何立即返回一个承诺,但只有在工作完成并且我们想取消计时器时才解决它。 另请注意,您不再需要使用$q.when

    【讨论】:

      【解决方案3】:

      我认为您没有看到任何内容,因为在区间内您的变量的范围松动,您需要让范围知道您已经使用 $scope.$apply 进行了更改。

      所以你的代码应该是这样的。

             var timer = $interval(function() {
                  if (i < content.length){
                      $scope.typewriter += content[i];
                      $scope.$apply();
                  else {
                      $interval.cancel(timer);
                  }
                  i++;
      
              }, 300)
      

      【讨论】:

      • 它不起作用..我添加了 $scope.$apply 并尝试从函数中取出 $scope.typewriter="" 但这也没有帮助..
      • 不,您不需要$scope.$apply。打字机已经是一个 $scope 变量,而 $interval 是一个 Angular 原生服务。
      猜你喜欢
      • 2016-08-06
      • 1970-01-01
      • 2018-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-29
      • 2017-05-11
      相关资源
      最近更新 更多