JavaScript中的承诺(angular)



我是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}}显示。

如果您需要处理数据而不仅仅是显示数据,那么您可能需要使用另一个答案所建议的服务

相关内容

  • 没有找到相关文章

最新更新