Angularjs ui-router resolve不会等待所有承诺

时间:2017-12-02 20:32:33

标签: angularjs angular-ui-router

目前,我在等待我的承诺通过解决方案时遇到了麻烦。 我理解这是因为它是一个异步调用,因此解决方案不会等待所有的承诺,只是传递部分数据来解决。

我试过搜索很多论坛,但我似乎无法让它发挥作用。

所以这是我的主页。

angular.module('app', ['ui.router', 'chart.js'])
    .config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
        $urlRouterProvider.otherwise('/');
        $stateProvider
            .state('redditAnalyzer', {
                url: '/analyze/:name',
                component: 'redditAnalyzer',
                resolve: {
                    resolve:
                    ['test', '$stateParams', function (test, $stateParams) {
                        var data = test.getAnalysisData($stateParams.name);
                        return data;
                    }
                    ]
                }
            })
            .state('home', {
                url: '/',
                component: 'home'
            });
    }]);

一旦我输入我的用户名,它就会改变状态。 在我的app.js中我有

angular.module('app')
    .factory('test', ['$http', '$state', '$q', function ($http, $state, $q) {
        var vm = this;

        vm.accountData = {};
        vm.after = '';
        vm.bestComment = {};
        vm.bestComment.karma = 0;
        vm.userName;
        vm.bestComment.date = '';
        vm.subreddit = {};
        vm.myChart;

        vm.getAnalysisData = function (redditUser) {
            vm.userName = redditUser;
            vm.resetData(redditUser);
            vm.getAccountInfo(redditUser);
            vm.getAllComments(redditUser);
            return {
                accountData: vm.accountData,
                bestComment: vm.bestComment,
                userName: vm.userName,
                subreddit: vm.subreddit,
                myChart: vm.myChart
            };
        }

        vm.resetData = function (user) {
            vm.accountData = {};
            vm.after = '';
            vm.bestComment = {};
            vm.bestComment.karma = -(Math.pow(2, 53) - 1);
            vm.userName = user;
            vm.date = '';
            vm.subreddit = [];
            vm.topThreeSub = [];
        }

        vm.getAccountInfo = function (user) {
            $http.get('https://www.reddit.com/user/' + user + '/about.json')
                .then(function (response) {
                    vm.accountData = response.data.data;
                    vm.accountData.total_karma = vm.accountData.comment_karma + vm.accountData.link_karma;
                    console.log("I got the account info!");
                });
        }
        vm.getAllComments = function (user) {
            $http.get('https://www.reddit.com/user/' + user + '/comments.json' + vm.after)
                .then(
                function (response) {
                    console.log("I got the comment info!");
                    tempResponse = response;
                    var data = response.data.data
                    vm.after = '?after=' + data.after;
                    for (i = 0; i < data.children.length; i++) {
                        if (vm.bestComment.karma < parseInt(data.children[i].data.score)) {
                            vm.bestComment.karma = parseInt(data.children[i].data.score);
                            vm.bestComment.comment = data.children[i].data.body;
                            vm.bestComment.date = (new Date(data.children[i].data.created * 1000)).toString();
                        }
                        var tempSub = data.children[i].data.subreddit;
                        if (vm.subreddit[tempSub] === undefined) {
                            vm.subreddit[tempSub] = 1;
                        }
                        else {
                            vm.subreddit[tempSub]++;
                        }
                    }
                    if (response.data.data.after != null) {
                        vm.getAllComments(user);
                    }
                }, function (error) {
                    console.log(error);
                    throw error;
                })
                .catch(function (error) { });
        }
        return {
            resolve: vm.resolve,
            hello: vm.hello,
            getAnalysisData: vm.getAnalysisData
        }
    }]);

我正在调用函数test.getAnalysisData来获取数据。

在我的test.js中我有

angular.module('app')
    .component('redditAnalyzer', {
        templateUrl: 'Content/app/components/redditAnalyzer.html',
        bindings: {
            resolve: '<'
        },
        controller: ['$http', 'test',
            function ($http, test) {
                var vm = this;
                vm.accountData = {};
                vm.bestComment = {};
                vm.bestComment.karma = 0;
                vm.userName;
                vm.bestComment.date = '';
                vm.subreddit = {};
                vm.myChart;

                vm.$onInit = function () {
                    console.log("this is the resolve", vm.resolve);
                    //vm.accountData = resolve.accountData;
                    //vm.bestComment = resolve.bestComment;
                    //vm.myChart = resolve.myChart;
                    //vm.subreddit = resolve.subreddit;
                    //vm.userName = resolve.userName;
                }

            }]
    });

我递归调用函数vm.getAllComments,因为它是如何工作的,vm.getAllComments将获得该帐户的前25条评论,然后从响应的部分信息,我可以在帐户中获得接下来的25条评论

最后,在我的redditanalyzer文件中,我有

this is the resolve {accountData: {…}, bestComment: {…}, userName: "spez", subreddit: Array(0), myChart: undefined}accountData: {}bestComment: {karma: 22200, comment: "Reddit search might work by then.", date: "Thu Oct 27 2016 01:07:22 GMT-0400 (Eastern Daylight Time)"}myChart: undefinedsubreddit: [blog: 10, announcements: 475, modnews: 34, programming: 32, ModSupport: 20, …]userName: "spez"__proto__: Object
test.js:44 I got the account info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
7test.js:51 I got the comment info!

你可以在我的控制台中看到问题。

this

它甚至在做出承诺之前就改变了路线。 我该怎么办才能等待所有的承诺呢?

2 个答案:

答案 0 :(得分:1)

解析器不会等待承诺,因为代码不会向解析器返回承诺。

getAllComments函数需要返回一个承诺:

    vm.getAllComments = function (user) {
         ̲r̲e̲t̲u̲r̲n̲ $http.get('https://www.reddit.com/user/' + user + '/comments.json' + vm.after)
            .then(
            function (response) {
                console.log("I got the comment info!");
                tempResponse = response;
                var data = response.data.data
                vm.after = '?after=' + data.after;
                for (i = 0; i < data.children.length; i++) {
                    if (vm.bestComment.karma < parseInt(data.children[i].data.score)) {
                        vm.bestComment.karma = parseInt(data.children[i].data.score);
                        vm.bestComment.comment = data.children[i].data.body;
                        vm.bestComment.date = (new Date(data.children[i].data.created * 1000)).toString();
                    }
                    var tempSub = data.children[i].data.subreddit;
                    if (vm.subreddit[tempSub] === undefined) {
                        vm.subreddit[tempSub] = 1;
                    }
                    else {
                        vm.subreddit[tempSub]++;
                    }
                }
                if (response.data.data.after != null) {
                     ̲r̲e̲t̲u̲r̲n̲ vm.getAllComments(user);
                } else {
                     ̲r̲e̲t̲u̲r̲n̲ ̲v̲m̲.̲b̲e̲s̲t̲C̲o̲m̲m̲e̲n̲t̲;̲
                }
            }, function (error) {
                console.log(error);
                throw error;
            })
            ̶.̶c̶a̶t̶c̶h̶(̶f̶u̶n̶c̶t̶i̶o̶n̶ ̶(̶e̶r̶r̶o̶r̶)̶ ̶{̶ ̶}̶)̶;̶
    }

使用$q.all创建等待多个承诺的承诺:

    vm.getAnalysisData = function (redditUser) {
        vm.userName = redditUser;
        vm.resetData(redditUser);
        vm.getAccountInfo(redditUser);
        ̲v̲a̲r̲ ̲a̲l̲l̲C̲o̲m̲m̲e̲n̲t̲s̲P̲r̲o̲m̲i̲s̲e̲ ̲=̲ vm.getAllComments(redditUser);
        return $q.all({
            accountData: vm.accountData,
            bestComment: vm.bestComment,
            userName: vm.userName,
            subreddit: vm.subreddit,
            myChart: vm.myChart,
            ̲a̲l̲l̲C̲o̲m̲m̲e̲n̲t̲s̲:̲ ̲a̲l̲l̲C̲o̲m̲m̲e̲n̲t̲s̲P̲r̲o̲m̲i̲s̲e̲
        });
    }

有关详细信息,请参阅

答案 1 :(得分:0)

我还有,您使用的是什么版本的ui-router?关于最新的'$ stateParams'已被弃用并且已经过期$ $。

此外,您不需要使用此

url: '/analyze/:name',
  

在UI-Router legacy中,URL路径中的参数是可选的。   如果在URL中找不到该参数,则它将与空匹配   字符串。

您可以替换为:

url: '/analyze/', 

params: {
    name: ""
  }

您可以阅读迁移guid