【问题标题】:Deferred promise not deferring延期承诺不延期
【发布时间】:2013-12-28 05:28:18
【问题描述】:

嗨,在下面的 Angular 控制器中,我尝试使用 Parse.com 启动 facebook 登录。 所以我创建了一个在 fbLogIn 上触发的承诺。它应该做的是首先登录 facebook,然后获取 first_name 并将其存储在 fieldValuesService.ff 中。 然后,它应该访问这个值并用它做一些事情。出于说明目的,我只使用了控制台日志。 发生的情况是第二个 console.log 在第二个 then 之前被触发,在第一个 .then 之前被触发,因此是未定义的。 我不明白为什么在这种情况下,第二个 .then 中的任何内容都可以在第一个之前触发。

还有第二个问题,在注销后,fbLogIn 函数有时会处于非活动状态:它不会再次触发登录过程。

如果您对此问题有所了解,我们将不胜感激。

.controller('logController',
    function ($scope, $q, fieldValuesService) {
        var defer = $q.defer();

         defer.promise
         .then(function() {
                 Parse.FacebookUtils.logIn(null, {
                     success: function(user) {
                         if (!user.existed()) {
                             alert("User signed up and logged in through Facebook!");
                         } else {
                             $scope.currentUser = user;
                             $scope.$apply();
                             FB.api('/me', function(response) {
                                 fieldValuesService.ff = response.first_name;
                                 console.log(fieldValuesService.ff); //logs bob

                             });
                         }
                     },
                     error: function(user, error) {
                         alert("User cancelled the Facebook login or did not fully authorize.");
                     }
                 });
             })
         .then(function(){
                 console.log(fieldValuesService.ff); //logs undefined
         });


        $scope.fbLogIn = function() {
               defer.resolve();

           };

         // Parse log out
        $scope.logOut = function(form) {
            Parse.User.logOut();
            $scope.currentUser = null;

        };
    });   

【问题讨论】:

  • 我认为您的问题可能是您的第一个 then 没有返回执行第二个 then 的承诺。
  • 我打赌FB.api 是异步的,这意味着function(response) 在第二个then 处理程序之后被调用。
  • 我在自己的 then 处理程序中添加了 FB.api: .then(function(){ FB.api('/me', function(response) { return response; }) ; 然后访问它在接下来的处理程序中,但仍然遇到同样的问题

标签: angularjs promise


【解决方案1】:

也许如果你重构你的代码,事情会变得容易一些。

我建议将所有与 FB 相关的内容重构为自己的服务,例如:

module.factory('FBService', function ($q) {
    var login,
    logout,
    getInformation;
    login = function () {
        var defered = $q.defer();
        Parse.FacebookUtils.logIn(null, {
            success: function (user) {
                defered.resolve(user);
            },
            error: function (user, error) {
                defered.reject(user, error);
            }
        });
        return defered.promise;
    };
    logout = function () {
        var defered = $q.defer();
        Parse.User.logOut();
        defered.resolve();
        return defered.promise;
    };
    getInformation = function () {
        var defered = $q.defer();
        FB.api('/me', function (response) {
            defered.resolve(response);
        });
        return defered.promise;
    }
    return {
        login: login,
        logout: logout,
        getInformation: getInformation
    };
});

module.controller("LoginCtrl", function ($scope, FBService, fieldValuesService) {
    $scope.fbLogIn = function () {
        FBService.login().then(function (user) {
            $scope.currentUser = user;
            return FBService.getInformation();
        }).then(function (information) {
            fieldValuesService.ff = information.first_name;
            console.log(fieldValuesService.ff);
        });
    };
    $scope.logOut = function () {
        FBService.logout().then(function () {
            $scope.currentUser = null;
         });
    };
});

【讨论】:

  • 感谢您的出色回答。它按预期工作。这些有助于从不同方向解决实际问题的帖子总是很有启发性。如果我添加更多 .then 处理程序将值传递给下一个 .then 处理程序,不需要工厂处理,它们会被延迟,还是我必须通过工厂/延迟/承诺传递?
猜你喜欢
  • 2013-06-22
  • 1970-01-01
  • 2015-03-08
  • 1970-01-01
  • 2015-03-27
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多