2016-05-10 3 views
1

Я хочу спросить может then() использовать для любой функции?JS Promises - 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); 
    }); 
} 

А потом я хочу, чтобы вызвать этот метод, а затем (и только тогда) вызвать другую строку кода раз Thats завершено, который был я буду использовать then:

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

Это дает мне ошибку - интересно, что я делаю неправильно?

Благодаря

+0

.Это не волшебство, его просто доступно только для объектов Promises. – YOU

ответ

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); 
    }); 
} 
+0

Спасибо - так просто, как добавить 'return'? – userMod2

-1

Нет, вы можете использовать только тогда на $ обещании.

Таким образом, только это будет работать:

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

.then() не может быть использован на любой функции. Только функция, которая возвращает некоторую форму обещания.

Я бы рассмотрел документы MDN по Promises, Promise.prototype.then и обещал в угловом формате с использованием $q.

В вашем случае только commentsService.getComments($routeParams.id) возвращает Promise, поэтому на него можно набрать .then().

commentsService.getComments($routeParams.id).then() также возвращает обещание, которое разрешается после выполнения функции в блоке .then(), поэтому вы можете просто добавить return, чтобы связать созданное обещание. Было бы то же самое, как вызов:

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); 
     }); 
} 
+0

Но этот метод * может * вернуть обещание, позволяя ему быть дальше прикованным. Это половина ответа. – Jamiec

+0

Спасибо, я понимаю сейчас, поэтому в ответе выше @aseferov - это решение так же просто, как добавление 'return' – userMod2

+0

@Jamiec. Согласен. Ответ обновлен. Я был немного смущен вопросом. Не удалось определить, хотел ли он этого поведения. – mgmcdermott

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="[email protected]" 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>

Смежные вопросы