【问题标题】:Cancel or stop a $timeout in a recursive promise chain取消或停止递归承诺链中的 $timeout
【发布时间】:2015-02-13 04:17:45
【问题描述】:

我有一项服务,它每 3 秒检查一次项目状态。如果项目状态为就绪,则返回状态字符串。否则,请使用$timeout 等待 3 秒,然后重试。

我的问题是当用户触发某些事件(例如:离开当前页面)时,我想取消或停止递归超时,但我不知道该怎么做。

服务:

angular.module('app')
    .factory('ItemService', ItemService);

function ItemService($timeout, DataService) {
    var service = {
        checkStatus: checkStatus
    };

    function checkStatus() {
        return DataService.getItemStatus()
            .then(function(status){
                if (status === 'ready') {
                    return status;
                } else {
                    // the item is not ready. Check again after 3 seconds
                    return $timeout(function() {
                        return checkStatus();
                    }, 3000)
                }
            });
    }

}

客户:

angular.module('app')
    .controller('ItemCtrl', ItemCtrl);

function ItemCtrl($scope, ItemService) {
    ItemService.checkStatus()
        .then(function(status) {
            // do somethin when item is ready.
        });

    $scope.$on('destroy', function(){
        // Should stop the $timeout recursive, but don't know how..
    });
}

【问题讨论】:

  • 您可能会为某些事件附加一个布尔值,然后在您的状态检查中,还检查是否触发了其中一个事件
  • 如果只需要检查一项,可以解决问题。如果在同一页面上要检查两个项目,而我有时只想停止其中一个项目怎么办?
  • 我也有同样的问题,希望得到解答。
  • 如果getItemStatus 已经返回了一个promise,为什么它会在状态真正准备好之前触发一个resolve?
  • @rgthre my getItemStatus 实际上是对后端服务器的 GET 请求,它将立即返回带有字符串 readyprocessing 的项目状态,因此只要后端返回字符串。

标签: javascript angularjs recursion


【解决方案1】:

您应该能够取消角度超时

$timeout.cancel(promise)

所以这样的事情应该可以工作:

var promise = ItemService.checkStatus();
promise.then(function(status) {
        // do somethin when item is ready.
    });

$scope.$on('destroy', function(){
    if(typeof promise.then === 'function') {
        $timeout.cancel(promise);
    }
});

【讨论】:

  • 谢谢,这可能解决了问题,但它给我带来了另一个问题:我如何检查destroy 函数中的承诺是否是$timeout 承诺?
  • 好问题 - 如果你愿意,你应该安全地取消字符串,但要检查它是否是一个承诺,我想我会检查对象是否有一个名为 'then' 的函数随附的。我会更新我的答案。
  • 但是,检查then 函数并不能解决问题,因为就绪条件返回的对象也可能是一个承诺。
  • 您可以检查 $$timeoutId 字段,我认为该字段特定于 Angular 的超时承诺。这至少可以确保它是一个角度超时,尽管它不能确保它是正确的角度超时。
猜你喜欢
  • 1970-01-01
  • 2014-12-29
  • 1970-01-01
  • 2013-02-08
  • 1970-01-01
  • 1970-01-01
  • 2016-04-02
  • 1970-01-01
  • 2014-02-04
相关资源
最近更新 更多