Angular.js中的2个控制器之间存在竞争条件问题,带有Ajax和localStorage值

Issue with race condition betwen 2 Controllers in Angular.js with Ajax and a localStorage value

本文关键字:带有 问题 Ajax localStorage 条件 竞争 中的 js 2个 控制器 存在      更新时间:2023-09-26

myIdentity的值只创建一次,并且在首次使用以下Angular.js控制器后,会永久保存在本地存储中。

函数$scope.createIdentity((是全局控制器中的一个复杂函数,它将结果保存到$localstorage.myIdentity。这非常有效!!!createIdentity((函数在其内部使用Q promise。但在AppCtrl中,我遇到了竞争条件的问题,因为$localstorage.myIdentity以前尚未解决我的$http XHR请求被激发。所以它不包含myId的任何值。

这种情况仅在第一次使用控制器时发生。

但我需要在第一次调用AppCtrl时启动socket.io连接,这对我来说是一个更大的问题

第二次使用AppCtrl时,$localStorage中还提供了myIdentity的正确值。

TimeacleControllers.controller('StatusCtrl', ['$scope', '$http', 'Socket', '$localStorage',
function ($scope, $http, Socket, $localStorage) {

    if ($localStorage.myIdentity === undefined) {
        $scope.createIdentity();
    }
    var myParams = {
        myId:  $localStorage.myIdentity
    };
    $http
        .post('http://example.org', myParams)
        .success(function (data) {
            console.log('received data: ' + data);
            Socket.connect();
            Socket.on('connected', function () {
                console.log("Connection!");
            });
            Socket.on('message', function (msg) {
                console.log("Message: " + msg);
            });
        })
        .error(function (err) {
            // Handle login errors here
            console.log("Error - " + err);
        });
}]);

那么,您可以在这里做些什么来让Ajax请求等待$localstorage.myIdentity得到解决呢?请帮忙。

您提到了Q promise,但异步序列有问题。。。?

如果createIdentity返回promise,只需将http调用放入.then 中即可

$scope.createIdentity().then(function() {
    $http.... // or you can wrap it inside a function
})

编辑:如果您无法访问填充变量的代码(通常发生在指令内部(,您可以设置一个一次性监视来监视值的变化。

var unwatch = $scope.$watch(function(){
  return $localStorage.myIdentity;
}, function(newValue){
  if (newValue === undefined) return;
  $http...
  unwatch();
});

您说过$scope.createIdentity()使用promise(可能是异步操作(。让它返回一个让代码遵守的承诺。当它解析时,让它解析身份。

承诺是可链接的。当您从then返回一个promise时,下一个then将侦听该promise而不是原始promise。在这种情况下,我们让下一个then监听AJAX。

$scope.createIdentity().then(function(identity){
  // When createIdentity resolves, use the data for the AJAX.
  // Return the AJAX promise for the next chained then.
  return $http.get(...);
}).then(function(data){
  // When the AJAX completes, use the data for the socket call
  Socket.connect();
  ...
});