Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 等待承诺?_Javascript_Angularjs_Promise - Fatal编程技术网

Javascript 等待承诺?

Javascript 等待承诺?,javascript,angularjs,promise,Javascript,Angularjs,Promise,我有以下angularjs代码: $scope.clients = commonFactory.getData(clientFactory.getClients()); if ($scope.clients.length > 0) { $scope.sampleForm.ClientId = $scope.clients[0].ClientId; } 以及commonFactory中的getData函数: factory.getData = function (method) {

我有以下angularjs代码:

$scope.clients = commonFactory.getData(clientFactory.getClients());
if ($scope.clients.length > 0) {
    $scope.sampleForm.ClientId = $scope.clients[0].ClientId;
}
以及commonFactory中的getData函数:

factory.getData = function (method) {
    method.then(function (response) {
        return response.data;
    }, function (error) {
        $rootScope.alerts.push({ type: 'error', msg: error.data.ExceptionMessage });
    });
};
问题是$scope.clients.length由于异步调用而在到达该行时未定义

在我知道已分配$scope.clients之前,是否有方法不进行长度检查?我看过这样的东西:

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

尝试链接我的
然后
承诺,但没有骰子。。。这里的目标是让getData方法避免一堆用于捕获错误的样板代码。。。也许我错了?

这是承诺所针对的最基本的情况。开始异步操作时,只需使用
var deferred=$q.deferred()
做出承诺,异步操作完成后,使用
deferred.resolve(result)
解析承诺,并在函数中返回
deferred.promise
。Angular的异步方法在内部执行此操作,并且已经返回了承诺,因此您可以只返回那些相同的承诺,而不是使用
$q.defer()
创建新的承诺。您可以将
附加到任何返回承诺的内容上。此外,如果从
then
函数返回一个值,该值将被包装在一个承诺中,以便
then
链可以继续

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;
  });
})
这里有一个更有趣的链接:

.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'
  });
})

我用现场演示更新了我的答案。如果您有任何问题,请告诉我。@m59问题如下:)这太棒了,谢谢。但有一个问题-虽然我注意到在我的示例中,$scope.clients填充正确,但从$scope.clients[0].ClientId设置ClientId的调用不起作用。那么回到原来的问题上来吧…?@Nicros你会一直遇到这样的问题,直到你更好地理解如何用角度来处理问题。你的代码到处都是。如果您对代码进行现场演示,我将能够帮助您更好地清理代码。我需要实际了解代码中提到的那些“方法”。呃,当我删除“长度”时,你的代码可以工作:)我的代码仍然不能工作。将处理一个更好的示例并更新它。。。不过,等会儿再做…@Nicros是的,你还是没抓住重点。没关系,大多数人一开始都是这样(我是这样做的)。我刚才回答了一个非常类似的问题:参见第一种方法。此外,重复我在那里留下的评论,控制器不必担心如何/何时获取数据,这就是服务的用途。让服务在数据准备好时发送长度(承诺已解决)。需要该长度的唯一原因是您是否打算显示它,因此我假设这是您的计划。也就是说,我认为使用服务设置为您提供该价值没有问题。这正是我在之前的评论中所做的回答。一个服务方法返回所有项,而另一个方法只返回请求的项。另外,请注意缓存,以便ajax调用不会不必要地触发。