$ q.all仅适用于第一次通话

问题描述:

不确定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; 
    } 
}); 

允诺只能使用一次解决。您的服务始终回报相同的承诺。一旦解决,它就解决了。

您正在使用反模式,顺便说一句。 $超时已经返回一个承诺。所有你应该有你的服务是

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

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

相同的服务2,顺便说一句。但是由于两种服务都是完全相同的(除了超时期限外),并且不执行$ timeout尚未完成的任何操作,所以可以直接从控制器使用$ timeout。

+0

感谢您的快速响应。我只是在玩q.all。事实上,我有一个复杂的问题。我有多个服务调用进行服务器端数据库调用,我想至少等待其中的几个完成处理其余代码。这就是为什么我使用服务进行模拟的原因,但我认为q和timeout的双重用法都会导致问题的答案。你的建议解决了这个问题。 – user1829319