【问题标题】:$q.all works for the first call only$q.all 仅适用于第一次通话
【发布时间】:2017-06-03 12:32:50
【问题描述】:

不确定为什么 q.all 第二次无法正常工作,例如第二次它不等待所有的承诺都被解决。

请查看示例并按下“呼叫服务”按钮。第一次它会等到两个承诺都得到解决,但如果你再次按下按钮它会立即响应,不知道为什么?

http://plnkr.co/edit/JNJmX1fjsmxrxYuiNHJb?p=preview

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

app.controller('MainCtrl', function($scope, $q, MyService1, MyService2) {
  $scope.name = 'World';

  $scope.Status1 = 'Waiting';
  $scope.Status2 = 'Waiting';
  $scope.buttonValue = "Call Services";

  $scope.doServices = function() {

    $scope.Status1 = 'Waiting';
    $scope.Status2 = 'Waiting';
    $scope.buttonValue = "Working ...";
    console.log($scope.Status1)

    var promise1 = MyService1.doIt();
    var promise2 = MyService2.doIt();

   $q.all([promise1, promise2]).then(
      function() {
        $scope.Status1 = 'Done';
      },
      function() {
        $scope.Status1 = 'Failed';
      }
    ).finally(function() {
      $scope.Status2 = 'Done waiting';
      $scope.buttonValue = "Call Services";
      //promises = null;
    });

  }

  $scope.callServices = function() {
     $scope.Status1 = 'Waiting';
  $scope.Status2 = 'Waiting';
    $scope.doServices();
  }

  $scope.reset = function() {
    $scope.Status1 = 'Waiting';
    $scope.Status2 = 'Waiting';
  }

});

app.service("MyService1", function($q, $timeout) {

  var deferred = $q.defer();

  this.doIt = function() {
    $timeout(function() {
      console.log("Service 1 called!");
      deferred.resolve("Service 1 done!");
    }, 2000);

    return deferred.promise;
  }
});


app.service("MyService2", function($q, $timeout) {

  var deferred = $q.defer();

  this.doIt = function() {
    $timeout(function() {
      console.log("Service 2 called!");
      deferred.resolve("Service 2 done!");
    }, 5000)

    return deferred.promise;
  }
});

【问题讨论】:

    标签: angularjs q


    【解决方案1】:

    一个promise只能被解决一次。您的服务总是返回相同的承诺。解决了就解决了。

    顺便说一句,您正在使用反模式。 $timeout 已经返回了一个承诺。您在服务中应该拥有的只是

    app.service("MyService1", function($timeout) {
    
      this.doIt = function() {
        return $timeout(function() {
          console.log("Service 1 called!");
          return "Service 1 done!";
        }, 2000);
      }
    });
    

    服务 2 也是如此,顺便说一句。但是由于这两个服务都是完全相同的事情(除了超时的持续时间),并且不做任何 $timeout 还没有做的事情,你可以直接从你的控制器中使用 $timeout。

    【讨论】:

    • 感谢您的快速回复。我只是在玩q.all。实际上,我有一个复杂的问题。我有多个执行服务器端数据库调用的服务调用,我想至少等待其中几个完成处理其余代码。这就是我用服务模拟的原因,但我认为 q 和 timeout 的双重使用都返回了导致问题的承诺。您的建议解决了问题。
    • 那有什么解决办法???如何重用已解决的承诺。有没有办法重新初始化promise???
    • 解决方案在响应中:每次调用服务时创建并返回一个新的promise。
    猜你喜欢
    • 2023-04-03
    • 2023-03-08
    • 1970-01-01
    • 2013-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多