2016-04-14 17 views
0

Ich habe den folgenden Code in meinem Javascript-Controller. Die Funktionen funktionieren, wenn sie unabhängig und asynchron aus der Sicht aufgerufen werden. Allerdings möchte ich sie synchron auf Seite laden nennen, wie die Rückkehr Wert aus der ersten Funktion in dem Aufruf für die zweite FunktionAngular Promise läuft nicht synchron

$scope.function1= function() { 
    $http({ 
     url: '/Class/method1/', 
     method: 'GET' 
    }).success(function (data) { 
     $scope.mygrid= data.data; 
     $scope.myvalue= $scope.mygrid[0]; 
    }); 
}; 

$scope.function2= function() { 
    $http({ 
     url: '/class/method2/', 
     method: 'POST', 
     params: { myValue: $scope.myvalue } 
    }).success(function (data) { 
     $scope.myValue2 = data.data; 
    }); 
}; 

var initialize = function() { 
    var defer = $q.defer(); 
    defer.promise 
     .then(function() { 
      $scope.function1(); 
     }) 
     .then(function() { 
      $scope.function2(); 
     }) 
defer.resolve(); 
    }; 
initialize(); 

Auf dem zweiten Aufruf $ scope.myvalue verwendet wird, ist null. Daten wurden von Funktion eins zurückgegeben, so dass ich nur daran denken kann, dass Funktion2 zu früh aufgerufen wird. Irgendwelche Zeiger? :-)

+1

Versprechen nie synchron sind. [Versprechen sind keine Magie] (http://stackoverflow.com/a/22562045/1048572). Sie müssen sie von den 'then'-Callbacks und von Ihrem Scope' functionN' zurückgeben, sonst können sie nicht wissen, dass Sie auf etwas warten wollen. – Bergi

+0

Wenn Sie möchten, dass function2 nach function1 ausgeführt wird, sollte es bei Erfolg von function 1 oder woanders aufgerufen werden, nachdem function1 die erwarteten Daten zurückgegeben hat. –

Antwort

1

Das Versprechen in initialize läuft synchron. Während $http Anfragen nicht. Dies führt zum Aufruf $scope.function2, ohne auf eine Zusage in $scope.function1 zu warten, um zu lösen.

Es sollte is antipattern, in diesem Fall

$scope.function1= function() { 
    return $http... 
}; 

$scope.function2= function() { 
    return $http... 
}; 

sein Versprechen abgegrenzt und initialize sollte, dass so kurz und prägnant sein:

var initialize = function() { 
    return $scope.function1().then(function() { 
      return $scope.function2(); 
    }) 
    }; 
-1
$http({ 
     url: 'url', 
     method: 'GET' 
    }) 

das ist auch eine Art Versprechen, so dass es async laufen wird.

$scope.function1= function() {//3rd step 
    $http({ 
     url: '/Class/method1/', 
     method: 'GET' 
    }).success(function (data) { 
     $scope.mygrid= data.data; //this run as asyn after response recived 
     $scope.myvalue= $scope.mygrid[0]; 
    }); 
}; 

$scope.function2= function() { //5th step 
    $http({ 
     url: '/class/method2/', 
     method: 'POST', 
     params: { myValue: $scope.myvalue } 
    }).success(function (data) { 
     $scope.myValue2 = data.data; //this run as asyn after response recived 
    }); 
}; 

var initialize = function() { 
    var defer = $q.defer(); 
    defer.promise 
     .then(function() { 
      $scope.function1(); //2nd step 
     }) 
     .then(function() { 
      $scope.function2(); //4th step 
     }) 
defer.resolve(); //1st step 
    }; 
initialize();