webentwicklung-frage-antwort-db.com.de

Warten auf ein Versprechen?

Ich habe den folgenden AngularJS-Code:

$scope.clients = commonFactory.getData(clientFactory.getClients());
if ($scope.clients.length > 0) {
    $scope.sampleForm.ClientId = $scope.clients[0].ClientId;
}

Und die getData-Funktion in commonFactory:

factory.getData = function (method) {
    method.then(function (response) {
        return response.data;
    }, function (error) {
        $rootScope.alerts.Push({ type: 'error', msg: error.data.ExceptionMessage });
    });
};

Das Problem ist, dass $ scope.clients.length aufgrund des asynchronen Aufrufs undefiniert ist, wenn es auf diese Zeile trifft.

Gibt es eine Möglichkeit, meine Längenprüfung erst dann durchzuführen, wenn ich weiß, dass $ scope.clients zugewiesen wurde? Ich habe mir so etwas angeschaut:

$scope.clients = commonFactory.getData(clientFactory.getClients()).then(function () {
    if ($scope.clients.length > 0) {
        $scope.sampleForm.ClientId = $scope.clients[0].ClientId;
    }
});

Ich versuche, meine then -Versprechen zu verketten, aber keine Würfel ... Ziel ist es, die getData-Methode zu verwenden, um eine Reihe von Boilerplate-Code zum Abfangen von Fehlern zu vermeiden ... Vielleicht mache ich das falsch?

31
Nicros

Dies ist die grundlegendste Situation, für die Versprechen gelten. Sie müssen lediglich mit var deferred = $q.defer() ein Versprechen abgeben, wenn Sie eine asynchrone Operation beginnen, das Versprechen mit deferred.resolve(result) auflösen, wenn die asynchrone Operation abgeschlossen ist, und deferred.promise In Ihrer Funktion zurückgeben . Angulars asynchrone Methoden tun dies intern und geben bereits Versprechungen zurück. Sie können also nur dieselben Versprechungen zurückgeben, anstatt mit $q.defer() neue Versprechungen zu erstellen. Sie können jedem, der ein Versprechen zurückgibt, einen .then Beifügen. Wenn Sie einen Wert aus einer then -Funktion zurückgeben, wird dieser Wert in ein Versprechen eingeschlossen, sodass die then -Kette fortgesetzt werden kann

angular.module('myApp', [])

.factory('myService', function($q, $timeout, $http) {
  return {
    myMethod: function() {
      // return the same promise that $http.get returns
      return $http.get('some/url');
    }
  };
})

.controller('myCtrl', function($scope, myService) {
  myService.myMethod().then(function(resp) {
    $scope.result = resp.data;
  });
})

Und hier noch ein bisschen mehr Spaß beim Verketten:

.factory('myService', function($q, $timeout, $http) {
  return {
    myMethod: function() {
      // return the same promise that $http.get returns
      return $http.get('some/url').then(function() {
        return 'abc';
      });
    }
  };
})

.controller('myCtrl', function($scope, myService) {
  myService.myMethod().then(function(result) {
    console.log(result); // 'abc'
    return someOtherAsyncFunc(); // for example, say this returns '123'
  }).then(function(result) {
    console.log(result); // '123'
  });
})
34
m59