所以我似乎仍然无法正确理解承诺。下面是一个控制器,它通过资源获取一系列帖子。它应该首先获取数组,然后将数组作为单独的函数加载到作用域中。这是行不通的,因为promise中的所有函数似乎仍然被同步调用。例如,名为getPosts()
的函数需要一秒钟,因为我在服务器上插入了延迟以模拟延迟。但是,尽管超过一秒钟,承诺中的所有其他功能同步调用。任何线索都会很棒。
var postController = myapp.controller('postController', function ($q, $rootScope, $scope, Post, $routeParams) {
var new_posts = []
$scope.new_post_count = 0
var getPosts = function () {
$scope.refreshing = true
var params = $routeParams
Post.query(params).
$promise.then(
function (response) {
$scope.refreshing = false;
new_posts = response
$scope.new_post_count = new_posts.length - $scope.posts.length
},
function (response) {
alert('Snap! ' + response.status)
}
)
}
$scope.refreshPosts = function () {
$scope.posts = new_posts
$scope.new_post_count = 0
}
/* all the functions below (marked 1, 2, 3) within the promise still called synchronously.
I thought they would wait until the previous function has finished? */
var defer = $q.defer()
defer.promise
.then(function () {
// 1
console.log('calling getposts')
getPosts()
})
.then(function () {
// 2
console.log('calling refresh posts')
$scope.refreshPosts()
})
.then(function () {
// 3
console.log('calling interval')
$interval(function () {
getPosts()
}, 7000, 0
)
})
defer.resolve()
答案 0 :(得分:2)
为什么不在refreshPosts
的回调中呼叫getPosts
。像这样:
var getPosts = function () {
$scope.refreshing = true
var params = $routeParams
Post.query(params).
$promise.then(
function (response) {
$scope.refreshing = false;
new_posts = response
$scope.new_post_count = new_posts.length - $scope.posts.length;
$scope.refreshPosts();
},
function (response) {
alert('Snap! ' + response.status)
}
)
}
如果您确实需要使用代码中的.then
来调用它。您需要在函数中返回一个承诺
var getPosts = function () {
var deferred = $q.defer();
$scope.refreshing = true;
var params = $routeParams
Post.query(params).
$promise.then(
function (response) {
$scope.refreshing = false;
new_posts = response
$scope.new_post_count = new_posts.length - $scope.posts.length;
deferred.resolve(response); //resolve deferred object
},
function (response) {
alert('Snap! ' + response.status);
deferred.reject(response); //reject deferred object
}
);
return deferred.promise; //return a promise.
}
然后修改你的承诺链接:
function Refresh(){
var defer = $q.defer()
defer.promise
.then(getPosts) //modify it here
.then(function () {
// 2
console.log('calling refresh posts')
$scope.refreshPosts();
})
.then(function () {
// 3
console.log('calling interval')
$interval(function () {
Refresh()
}, 7000, 0
)
})
defer.resolve();
};
答案 1 :(得分:2)
由于$timeout
也会返回promise,我们可以模拟流程。进一步,看看在promise链中我们返回下一个then(/*..*/)
的承诺:
var defer = $q.defer()
defer.promise.then(function () {
console.log('calling getposts');
return $scope.getPosts();
})
.then(function (result) {
$scope.data = result.data.results[0];
console.log('calling refresh posts')
return $timeout(function () {
console.log('refresh posts called');
}, 3000)
})
.then(function () {
console.log('calling interval')
$timeout(function () {
console.log('interval called')
}, 3000)
},
function (result) {
alert("Error: No data returned");
}
)
defer.resolve();
$scope.getPosts = function () {
return Data.query($scope.url);
}
请参阅 Fiddle 和控制台中的完整演示。
希望它会有所帮助
<强>许强>
承诺代表未来的价值,通常是未来的结果 一个异步操作,并允许我们定义什么 一旦这个值可用,或者当一个值出现时,就会发生 发生错误。
承诺链: