javascript - AngularJS $q promise 不会按预期工作

标签 javascript angularjs promise q

看来我还是没有正确理解promises。下面是一个 Controller ,它通过资源获取一系列帖子。它应该首先获取数组,然后将数组作为一个单独的函数加载到作用域中。这不起作用,因为 promise 中的所有函数似乎仍然被同步调用。例如,名为 getPosts() 的函数占用了一秒钟,因为我在服务器上插入了一个延迟来模拟延迟。但是尽管接管了一秒钟, promise 中的所有其他功能都被同步调用。任何线索都会很棒。

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()

最佳答案

你为什么不在 getPosts 的回调中调用你的 refreshPosts。像这样:

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 调用它。你需要在你的函数中返回一个 promise

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.
}

然后像这样修改你的 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();
};

关于javascript - AngularJS $q promise 不会按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20162031/

相关文章:

javascript - 如何在 Angular Controller 中应用foreach循环

JavaScript:无法动态重置动态创建的复选框的复选框值

angularjs - Angular 1.4.1 $cookies 最终成为 session cookie

javascript - jquery延迟执行顺序

javascript - 如何使 Backbone.js 集合项目独一无二?

javascript - JavaScript 中的静态数组变量?

javascript - AngularJS 和 HTML : Escaping quotes inside a variable for an onclick function

angularjs - 通过不处理选择更改值而不被选择来进行跟踪

javascript - 将 RSVP.js map idiom 移植到 bluebird

node.js - Bluebird 对具有返回值的函数进行 Promisify