JS Promises - Angular - 然后可以在任何函数上使用吗?

时间:2016-05-10 14:47:21

标签: javascript angularjs es6-promise

我想问一下then()可以在任何函数上使用吗?

在我的Angular应用程序中,我在尝试使用then时看到错误('无法读取未定义的属性')。

例如我有这个功能:

self.getCommentsData = function() {
  commentsService.getComments($routeParams.id)
  .then(function (data){
    //Do some stuff and at the end push to a scope array
    $scope.commentsList.push(someValue);
  });
}

后来我想调用这个方法,然后(只有这样)在完成后调用另一行代码,这就是我正在使用then

self.getCommentsData()
      .then(function(){
        $location.hash('goTotrue');
        $anchorScroll();
});

这给了我一个错误 - 想知道我做错了什么?

由于

4 个答案:

答案 0 :(得分:3)

你应该在链的功能中返回承诺

self.getCommentsData = function() {
  return commentsService.getComments($routeParams.id)
  .then(function (data){
    //Do some stuff and at the end push to a scope array
    $scope.commentsList.push(someValue);
  });
}

答案 1 :(得分:1)

.then()无法用于任何功能。只有一个返回某种形式的Promise的函数。

我会使用Promises审核Promise.prototype.then$q和Angular in Angular中的MDN文档。

在您的情况下,只有commentsService.getComments($routeParams.id)会返回一个承诺,因此可以在其上调用.then()

commentsService.getComments($routeParams.id).then()还会返回一个在.then()块中的函数运行后解析的Promise,因此您只需添加return即可链接创建的Promise。 它与调用相同:

commentsService.getComments($routeParams.id).then().then();

添加了return的代码:

  self.getCommentsData = function() {
    return commentsService.getComments($routeParams.id)
      .then(function (data){
        //Do some stuff and at the end push to a scope array
        $scope.commentsList.push(someValue);
      });
}

答案 2 :(得分:0)

您需要返回一个承诺,否则,仍会出现此错误。如果您看到angular documentation,就可以找到:

  

延迟对象的目的是公开关联的对象   Promise实例以及可用于发信号通知的API   成功或不成功完成,以及的状态   任务

为了说明这一点,我已经制作了这个片段:

angular
  .module("myApp", [])
  .controller("myCtrl", myCtrl)
  .service("myService", myService)
  
  myCtrl.$inject  = ["myService"];
  myService.$inject  = ["$q", "$timeout"];
  
  function myCtrl(myService){
    var vm = this;
    vm.data = [{user: "empty"}, {user: "empty"}, {user: "empty"}]
    vm.message = "Just wait 3 seconds to retrieve the data";
    
    myService.myPromise().then(function(res){
      //success case. The promise has been resolved
      vm.data = res;
      vm.message = "Promise resolved!";
      console.log("resultado");
      console.log(res);
    });
    
    
  }
  
  function myService($q, $timeout){
    this.myPromise = function(){
      var promiseObj = $q.defer(); //promise
      var dummyData = [{user: 1}, {user: 2}, {user: 3}];
      
      //this timeout is to ilustrate that the promise may take some time
      //you don't need to use the $timeout service
      $timeout(function(){
        promiseObj.resolve(dummyData); //promise resolved
      }, 3000);
      
      //promise resolved
      return promiseObj.promise;
      
    }
  }
<!DOCTYPE html>
<html ng-app="myApp">

<head>
  <script data-require="angular.js@1.3.14" data-semver="1.3.14" src="https://code.angularjs.org/1.3.14/angular.js"></script>
  <link rel="stylesheet" href="style.css" />
</head>

<body ng-controller="myCtrl as ctrl">
  <h1>Promise test</h1>
  <h2>Dummy data</h2>
  <h4>{{ctrl.message}}</h4>
  <ul>
    <li ng-repeat="data in ctrl.data">{{data.user}}</li>
  </ul>
</body>

</html>

答案 3 :(得分:-1)

不,你只能在$ promise上使用。

所以只有这样才能起作用:

commentsService.getComments($routeParams.id).then(function (data){
    $scope.commentsList.push(someValue);
});