Не понимаю JavaScript. Как сделать ожидание события загрузки данных?

  • Автор темы Автор темы xintrea
  • Дата начала Дата начала

xintrea

Новичок
Есть у меня "класс", у которого сделан метод init(). В нем происходит вызов метода load() для загрузки данных с сервера (по xmlrpc).

Задача: вызвать загрузку данных и дождаться результата. Если загрузка удачна - продолжить инит, если была ошибка - завершить инит.

Код:
// Глобальные переменные - статусы загрузки данных с сервера
var lb_load_status_ok=0;
var lb_load_status_in_process=1;
var lb_load_status_error=2;

...

function LBTeamData() 
{
 var loadStatus;

 this.init = function(id) 
 {
  // Загрузка с сервера информации
  this.load(id);
  
  // Ожидание завершения загрузки
  while( loadStatus==lb_load_status_in_process ){};

  // Если была ошибка  
  if(loadStatus==lb_load_status_error)
   return;
  
  // ... здесь продолжается инициализация ... 
 };
 

 this.load=function(teamId) 
 {
  loadStatus=lb_load_status_in_process;

  var that = this;

  // Получение данных о команде  
  $.xmlrpc({
        url: 'http://'+window.location.host+'/XmlRpcServer',
        methodName: 'getTeam',
        params: [teamId],
        success: function(response, status, jqXHR){ that.successLoad(response, status, jqXHR); },
        error: function(jqXHR, status, error) { that.errorLoad(jqXHR, status, error); }
  });

 };


 // Обработчик получения данных
 this.successLoad=function(response, status, jqXHR) 
 {
  loadStatus=lb_load_status_ok;

  name=response[0]['name']; // Название команды
  unitsNames=response[0]['unitsNames']; // Имена игроков

  alert("Success load data from server");
 };


 // Обработчик ошибки при получения данных
 this.errorLoad=function(jqXHR, status, error) 
 {
  loadStatus=lb_load_status_error;

  alert("Error at getting team data from server: "+error);
 };

}

Проблема в строке с циклом while(). На нем скрипт затыкается как на бесконечном цикле.

Если его убрать, то через некоторое время появится сообщение "Success load data from server". Это свидетельствует о том, что данные в подгружаются нормально.

Но я не могу понять, как в "линейном" коде метода init() дождаться появления этих данных. Флаги не помогают. Встраивать обработчики прямо в "линейный" код как лямбды - это издевательство, код получает рваный и плохо сопровождаемый.

Вопрос. Почему не работает этот кусок кода? Почему в цикле while() не отслеживаетс изменение свойства loadStatus? Как сделать чтоб отслеживалось?
 
так
PHP:
while( loadStatus==lb_load_status_in_process ){};
совершенно не правильно
у тебя есть на руках
PHP:
success: function(response, status, jqXHR){ that.successLoad(response, status, jqXHR); },
там загрузка произошла, от туда и пляши!
поломай свой мозг, думай callback'ами
 
поломай свой мозг, думай callback'ами

Я понял вас, но остался вот какой вопрос.

Предположим, переделал я LBTeamData.init() на цепочку вызовов:

Код:
this.init = function(id) 
 {
  // Загрузка с сервера информации
  this.load(id, this.init_second_callback() );
 }

this.init_second_callback = function() 
 {
  // Тут еще какие-то действия, еще какая-то подгрузка информации  
  this.loadFormula(id, this.init_third_callback() );
 }

this.init_third_callback = function() 
 {
  // Тут инит наконец-то завершен
  ...
 }

В load() и loadFormula(), точнее, в обработчиках событий получения данных, сделаны вызовы коллбаков. Все вроде понятно.

Однако помимо этого класса существует вышестоящий класс, который и вызывает инит экземпляра этого класса. И он тоже должен дождаться пока данный класс проинитится, перед тем как инитить следующие объекты.

Это что же получается, что и в вышестоящем классе надо все переделывать на цепочку функций, чтобы дожидаться инита вызываемого объекта?
 
если действие может быть сделано ТОЛЬКО после возникновения некоторого события, вызов этого действия пишем напосредственно в callback функции возникновения этого события.
для тебя
И он тоже должен дождаться пока данный класс проинитится, перед тем как инитить следующие объекты.
значит вызов данного инита должен быть в методе появления события о завершении.

если чесно звучит кривовато. возможно ему не нужно ждать, а "инится" параллельно? почему он должен дождаться?
 
> значит вызов данного инита должен быть в методе появления события о завершении.

То есть, городить огород с каллбаками придется и в вышестоящем коде. Блин, я сойду с ума, у меня четыре таких слоя.


> возможно ему не нужно ждать, а "инится" параллельно? почему он должен дождаться?

Потому что от тех данных, которые проинитится в объекте LBTeamData зависит логика инита дальнейших объектов.
 
все проще, не нужно ждать события, можно описать действия после его возникновения. 4й 10й слой не важно. пишем что нужно делать если это случилось в переданной лямде.
Потому что от тех данных, которые проинитится в объекте LBTeamData зависит логика инита дальнейших объектов.
может это уже не инит? в моем понимании инит это создание независимого от логики каркаса.

возможно тебе поможет знание, что можно создавать свои события и привязывать к этим событиям обработчик.

к примеру происходят 2 различных по цепочке события ajax.success и onchange, каждое из которых создает новое одинаковое событие "обновились данные", к которому привязан обработчик. обновления числа в элементе DOM

http://perevodik.net/ru/posts/17/
 
Сверху