2015-07-02 1 views
0

Значение myIdentity создается только один раз и сохраняется в локальном хранилище после первого использования следующего контроллера Angular.js.Проблема с состоянием гонки betwen 2 Контроллеры в Angular.js с Ajax и localStorage value

Функция $ scope.createIdentity() является сложной функцией в более глобальном контроллере и сохраняет результат в $ localstorage.myIdentity. Это прекрасно работает !!! Функция createIdentity() работает с Q-предложением для себя. Но в AppCtrl у меня проблема с условиями гонки, потому что $ localstorage.myIdentity еще не разрешен до мой запрос HTTP http XHR уволен. Поэтому он не содержит значения myId.

Это происходит только при первом использовании контроллера.

Но мне нужно запустить соединение socket.io при первом вызове AppCtrl, и это для меня большая проблема.

При втором использовании AppCtrl правильное значение myIdentity доступно еще в $ localStorage.

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 не может быть решена? Пожалуйста помоги.

+0

Если у вас есть эти ограничения, возможно, вам необходимо реорганизовать. Используйте службу для createIdentity и что-то вроде getid. Вы можете использовать обещание начать ваши вызовы сокетов, которые вы даже можете разрешить в маршрутизаторе, прежде чем маршрут будет изменен, если это необходимо. – jme11

ответ

1

Вы упомянули о обещании Q, но проблема с асинхронной последовательностью ...?

Если createIdentity возвращается обещание, просто поставить вызов HTTP внутри .then

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

Edit: Если у вас нет доступа к коду, который заселить переменную (обычно происходит внутри директивы) , вы можете настроить одноразовые часы для мониторинга изменения стоимости.

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

    $http... 

    unwatch(); 
}); 
+0

Конечно, это, конечно, не проблема, но это другое. CreateIdentity() должен запускаться только после того, как $ localstorage.myIdentity не установлен. В этом программном потоке я понятия не имею, как сделать запрос до тех пор, пока не будет сохранено значение $ localstorage.myIdentity. Я не сказал, что createIdentity() возвращает обещание. Он работает для себя с различными обещаниями, и если они все разрешены, он сохраняет Identity в localStorage. – gwinger

+0

обновлено, чтобы использовать '$ watch' – Icycool

+0

@lcycool: У меня нет идеи, что вы имеете в виду. Можете ли вы привести пример, соответствующий представленному мной коду? Я не могу видеть, где вы ждете $ scope.createIdentity(), чтобы сохранить значение. – gwinger

0

Вы сказали $scope.createIdentity() использует обещание (и, предположительно, является операцией асинхронной). Заставьте его вернуть обещание для вашего кода. Когда он будет разрешен, разрешите его идентифицировать.

Обещания связаны друг с другом. Когда вы возвращаете обещание от then, следующий then слушает это обещание вместо первоначального обещания. В этом случае мы делаем следующий 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(); 
    ... 
}); 
+0

Это ясно, но это не заполняет мои потребности. Позвольте мне попытаться пойти глубже. Я не хочу снова разрешать обещание createIdentity(), если доступно $ localstorage.myIdentity. Я уменьшил код успеха ajax. Я не всегда могу подключиться к нему. Так что это сложно. Я просто хочу подождать с полным блоком http, пока не будет доступно значение $ localstorage. – gwinger

+0

@gwinger Вы можете сохранить обещание 'createIdentity' в некоторой переменной. Прикрепление 'then' к уже разрешенному обещанию немедленно выполнит обработчик. – Joseph

+0

Можете ли вы привести пример? Я должен прочитать значение $ localStorage. Это возможно только для того, чтобы сделать ajax в моих обстоятельствах. Если он еще не установлен, я не могу выполнить Ajax. Я должен ждать только тогда. Функция идентификации является очень сложной функцией с высокими эксплуатационными затратами. Так что это будет плохой путь. – gwinger