【问题标题】:Accessing Data from outside a promise从 Promise 外部访问数据
【发布时间】:2023-04-04 06:12:01
【问题描述】:

我正在使用 angular 和 restangular,试图定义从我的 API 获得的默认标头。

Token var 永远不会用最终的 Token 定义。我或多或少明白为什么。但我还没有想出一种方法来从承诺中获得这种价值。我试过范围,什么没有。我尝试在承诺中调用默认标头。下面的这个 sn-p 显示了一些随机尝试的组合。

 angular
    .module('app')
    .run(function (Restangular, TokenService) {
        var Token;
        TokenService.get().then( function(data) {
               console.log(data.data); //The Correct Token from API
               Token = data.data;
               return data.data;
            }
        );

        Restangular.setDefaultHeaders({
            'X-XSRF-TOKEN': Token  //Token is undefined

        });
    });

如何正确地做到这一点?

【问题讨论】:

  • 角和矩形:)

标签: javascript angularjs promise restangular


【解决方案1】:

是的,以下代码将解决 JavaScript 使用闭包变量的问题。它将调用Restangular 来设置标头值。

angular
    .module('app')
    .run(function (Restangular, TokenService) {
       TokenService.get().then( function(data) {
           Restangular.setDefaultHeaders({
               'X-XSRF-TOKEN': data.data 
           });
        }
    );
});

但是,这种方法有什么问题呢?

TokenService 是一个异步服务,Angular 会开始获取令牌并继续初始化应用程序。使用Restangular 的指令或服务可能会尝试在TokenService.get(...) 完成之前执行需要该标头令牌的操作!

有三种可能的解决方案。

  • 忽略问题。
  • 使用状态变量指示令牌是否已设置,并等待其设置
  • 在 Angular 启动之前获取令牌。

首先获取令牌。在启动 Angular 之前,您必须使用 TokenService(我不知道它是什么)。

 angular.element(document).ready(function(){
        // first get token
        TokenService.get().then(function(data){
            // put the token somewhere
            window.token = data.data;
            // then start angular
            angular.bootstrap(document,['myApp']);
        });
 });

现在您可以在 Angular 启动时使用令牌。

angular
    .module('app')
    .run(function (Restangular) {
        Restangular.setDefaultHeaders({
           'X-XSRF-TOKEN': window.token
        });
    );
});

TokenService 是什么,在 Angular 开始之前如何获得它以及是否应该将内容放入 window 并不是真正的答案重点。我只是想确保您了解在应用启动和设置令牌之间存在滞后。所以最好先这样做。

【讨论】:

  • 你是对的。感谢您的详细信息和想法。确实,请求的异步性质导致了问题,因为 Angular 立即需要该值。虽然在发布我的问题之前我已经挣扎了好几个小时,但这显然是错误的解决方法。我放弃了令牌服务以获得更直接的 ajax 请求,该请求不基于承诺。 (现在我不能说我很清楚其中的区别),但问题立即得到解决,一切都很好。感谢您的帮助。
  • @csduarte 我已经使用 ui-route 对解析和子视图的支持解决了这个问题。我为所有其他子路由为/ 创建了一个父路由。该父级必须在开始之前解决获得令牌的承诺。这为整个应用创建了一个基本的启动承诺。
【解决方案2】:

将 Token 的访问权限移到 Promise 中。承诺的 .then 在 .run 完成后的某个时间运行,这就是 Token 未定义的原因。没有办法改变这种行为。

angular
    .module('app')
    .run(function (Restangular, TokenService) {
        TokenService.get().then( function(data) {
               console.log(data.data); //The Correct Token from API
               var token = data.data;
               Restangular.setDefaultHeaders({
                   'X-XSRF-TOKEN': token 
               });
               return data.data;
            }
        );

    });

【讨论】:

  • 另外值得注意的是,这仍然不会运行,因为token 拼写错误。 token != Token
  • 正确,而且我实际上也没有在.then函数中设置setter
  • 错字不是实际代码的一部分,只是在我为了清楚起见而重新输入时才引入的。我尝试了这种方法,并且在 Promise 中不再识别 Rectangular。
【解决方案3】:

如果您唯一需要令牌的是调用 setDefaultHeaders,您应该可以直接在 then 调用中执行此操作,例如:

    TokenService.get().then( function(data) {
        Restangular.setDefaultHeaders({
             'X-XSRF-TOKEN': data.data
            });
    });

如果您需要使令牌在整个应用程序中可用,我猜您可以在您的“运行”调用中注入“$rootScope”,然后在“那么”中您可以像这样分配它:

$rootScope.Token = data.data;

这应该使 Token 在你注入 $rootScope 的任何地方都可用;请记住,向 $rootScope 添加内容通常不是最好的主意。

【讨论】:

    猜你喜欢
    • 2020-11-30
    • 2015-04-06
    • 1970-01-01
    • 2019-01-15
    • 1970-01-01
    • 2021-06-29
    • 1970-01-01
    • 1970-01-01
    • 2014-04-05
    相关资源
    最近更新 更多