我是angular和http调用的新手。
然后我读到一些关于承诺呼叫。我完全无法理解。所以我需要一些帮助来知道我是否走对了方向。
我正在编程一个API,用于获取视频,以及有关它们的详细信息(视图等)与Youtube API v3。
但我似乎得到了一个错误的细节,因为我的数组是空的所有时间。
/*var promises = [];*/ // PROMISE
var videometrics;
var videodetails = [];
var deferred = $q.defer();
$http.get('https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId=' + playlistId + '&key=AIzaSyDQv-WpATIWLinCB3H_sH4W1sKx7plyvRA')
.success(function (response) {
for (var i = 0; i < response.items.length; i++) {
var video = {
id: response.items[i].snippet.resourceId.videoId,
title: response.items[i].snippet.title
};
$scope.video.push(video)
}
/*console.log($scope.video)
var promises = [];*/
for (i = 0; i < $scope.video.length; i++) {
/*console.log("looping")
console.log($scope.video)
console.log("Vi henter fra id:")
console.log($scope.video[i].id)*/
$http.get('https://www.googleapis.com/youtube/v3/videos?part=statistics&id=' + $scope.video[i].id + '&key=AIzaSyDQv-WpATIWLinCB3H_sH4W1sKx7plyvRA')
.success(function (responsevideo) {
/*console.log($scope.video[i].id);*/
// console.log("we are in the metric loop")
// console.log($scope.video[i].id)
// console.log($scope.video[i].title)
// console.log(responsevideo)
videometrics = {
id: responsevideo.items[0].id,
views: responsevideo.items[0].statistics.viewCount,
likes: responsevideo.items[0].statistics.likeCount,
dislikes: responsevideo.items[0].statistics.dislikeCount,
favorites: responsevideo.items[0].statistics.favoriteCount,
comments: responsevideo.items[0].statistics.commentCount
};
videodetails.push(videometrics);
deferred.resolve(responsevideo);
/*detailsOnVideos = $scope.videometrics;*/
})
/* videodetails.push(videometrics);*/
}
/*promises.push(videodetails);*/ // PROMISE
console.log(videodetails);
/* console.log(promises);*/ //PROMISE LOGGER
/* console.log(videodetails);*/
console.log($scope.video);
console.log("")
pagetokenarr = response.nextPageToken;
console.log(pagetokenarr)
});
return deferred;
/*return $q.all(promises);*/ // PROMISE
,正如你看到的我的第一个HTTP get,是功能性的,但下一个不是。我不明白为什么。但如果我推我的视频细节数组到承诺数组它的工作。一次又一次。我不知道为什么。
$http不需要$q。基本上有两种方法(据我所知)来处理$http:
1)创建一个服务,在那里隔离$http。像这样返回承诺:
return $http.get({params...}).then(function(data) {
return data.result;
});
那么在控制器中你会有:
SuperService.get(params...).then(function(data) { $scope.something = data; });
2)数据绑定!创建一个服务,把$http放进去。但是这次您将结果绑定到服务内部的对象。在这个服务中,你也有一个方法来返回那个对象。
$http.get({params...}).then(function(data) {
myObject = data.result;
});
然后在控制器中:
$scope.spiderman = SuperService.getObj();
SuperService.get(params...);
当你调用。get()时,AngularJS会变魔术并更新$scope。蜘蛛侠(当然,只要您从服务器获得响应)。
相关文献:
ngDocs
Lawson的"We have a problem with promises"
这是在这个柱塞工作的解决方案
你的代码工作得很好。问题是你的console.log()
被提前解雇了,因为它不在你承诺的.success()
或.then()
中。在$http
调用解析之前触发。
我重做了一点你的代码(特别是这些for
循环),使它更容易读。
你也不需要建立自己的承诺,直到$http
调用返回承诺
$http.get('https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId=' + playlistId + '&key=AIzaSyDQv-WpATIWLinCB3H_sH4W1sKx7plyvRA')
.success(function (response) {
angular.forEach(response.items, function(item){
var video = {
id: item.snippet.resourceId.videoId,
title: item.snippet.title
};
$scope.video.push(video);
})
console.log($scope.video);
angular.forEach($scope.video, function(video){
httpcalls.push($http.get('https://www.googleapis.com/youtube/v3/videos?part=statistics&id=' + video.id + '&key=AIzaSyDQv-WpATIWLinCB3H_sH4W1sKx7plyvRA')
.success(function (responsevideo) {
videometrics = {
id: responsevideo.items[0].id,
views: responsevideo.items[0].statistics.viewCount,
likes: responsevideo.items[0].statistics.likeCount,
dislikes: responsevideo.items[0].statistics.dislikeCount,
favorites: responsevideo.items[0].statistics.favoriteCount,
comments: responsevideo.items[0].statistics.commentCount
};
$scope.videodetails.push(videometrics);
}));
});
pagetokenarr = response.nextPageToken;
$q.all(httpcalls).then(function(){
console.log($scope.videodetails);
})
});
请注意,我将所有$http
调用推入一个集合(httpcalls
),并将console.log包装到一个$q.all(httpcalls).then()
函数中。这将等待,直到所有的$http
调用到集合被解析。
希望有帮助。
您的代码似乎工作良好。我已经删除了所有,但必需品,添加了变量,我需要作为占位符,因为我不确定的播放列表等。以下是我测试过的代码:
var app = angular.module('app', []);
app.controller('ctrl', function ($scope, $http) {
var videometrics;
$scope.videodetails = [];
var playlistId = "PL63F0C78739B09958";
$scope.video = [];
$http.get('https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId=' + playlistId + '&key=AIzaSyDQv-WpATIWLinCB3H_sH4W1sKx7plyvRA')
.success(function (response) {
for (var i = 0; i < response.items.length; i++) {
var video = {
id: response.items[i].snippet.resourceId.videoId,
title: response.items[i].snippet.title
};
$scope.video.push(video);
}
for (i = 0; i < $scope.video.length; i++) {
$http.get('https://www.googleapis.com/youtube/v3/videos?part=statistics&id=' + $scope.video[i].id + '&key=AIzaSyDQv-WpATIWLinCB3H_sH4W1sKx7plyvRA')
.success(function (responsevideo) {
var videometrics = {
id: responsevideo.items[0].id,
views: responsevideo.items[0].statistics.viewCount,
likes: responsevideo.items[0].statistics.likeCount,
dislikes: responsevideo.items[0].statistics.dislikeCount,
favorites: responsevideo.items[0].statistics.favoriteCount,
comments: responsevideo.items[0].statistics.commentCount
};
$scope.videodetails.push(videometrics);
});
}
});
});
当它在作用域中可用时,它将在浏览器中使用{{videodetails}}显示。
如果您需要处理数据而不仅仅是显示数据,那么您可能需要使用另一个答案所建议的服务