Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 31.05.2013, 23:41
Аспирант
Отправить личное сообщение для xintrea Посмотреть профиль Найти все сообщения от xintrea
 
Регистрация: 02.01.2011
Сообщений: 56

Не понимаю JavaScript. Как сделать ожидание события загрузки данных?
Есть у меня "класс", у которого сделан метод init(). В нем происходит вызов метода load() для загрузки данных с сервера (реализация jQuery 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? Как сделать чтоб отслеживалось?
Ответить с цитированием
  #2 (permalink)  
Старый 01.06.2013, 01:23
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,595

Сообщение от xintrea Посмотреть сообщение
Есть у меня "класс", у которого сделан метод init(). В нем происходит вызов метода load() для загрузки данных с сервера (реализация jQuery xmlrpc).

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

Сообщение от xintrea Посмотреть сообщение
Проблема в строке с циклом while(). На нем скрипт затыкается как на бесконечном цикле.
...
Вопрос. Почему не работает этот кусок кода? Почему в цикле while() не отслеживаетс изменение свойства loadStatus?
Так и должно быть. Цикл javascript не делим, пока он не отработает никакие внешние события ни на что повлиять не смогут.(именно по этому предложенный выше вариант работать не будет также как и ваш)

Сообщение от xintrea Посмотреть сообщение
Как сделать чтоб отслеживалось?
Никак. В javascript невозможна "приостановка" выполнения вручную, т.к. код выполняется в одном потоке и эта самая приостановка вызвала бы полное прекращение взаимодействия со страницей как таковой.(что вы и наблюдаете при вечном цикле). Событийная модель является единственным нормальным вариантом, позволяющим пользователю продолжать работу со страницей пока идут какие-либо фоновые процессы.

Сообщение от xintrea Посмотреть сообщение
Флаги не помогают. Встраивать обработчики прямо в "линейный" код как лямбды - это издевательство, код получает рваный и плохо сопровождаемый.
Если делать всё как вы привыкли в другом языке - возможно. Однако всё выходит красиво и аккуратно если не тянуть чуждую идеологию из других языков, а писать изначально на javascript.


P.S. Если вы ооочень этого хотите и вам глубоко покласть на идеологию javascript, то можно использовать синхронный ajax запрос(именно то что вам нужно - с ожиданием загрузки и полной остановкой работы). Но это делать крайне не рекомендуется. Пример.
__________________
29375, 35

Последний раз редактировалось Aetae, 01.06.2013 в 02:36.
Ответить с цитированием
  #3 (permalink)  
Старый 01.06.2013, 08:30
Аспирант
Отправить личное сообщение для xintrea Посмотреть профиль Найти все сообщения от xintrea
 
Регистрация: 02.01.2011
Сообщений: 56

> Сохраню кому нибудь рассудок, оставлю это здесь

Вы уверены, что этот код рабочий?

У вас же по сути генерируется куча xmlrpc запросов в цикле, пока самый первый запрос не отработает.
Ответить с цитированием
  #4 (permalink)  
Старый 01.06.2013, 08:39
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,595

Сообщение от xintrea Посмотреть сообщение
Вы уверены, что этот код рабочий?
Код нерабочий. Но не по этому:
Сообщение от xintrea Посмотреть сообщение
У вас же по сути генерируется куча xmlrpc запросов в цикле, пока самый первый запрос не отработает.
т.к. это неправда:
Сообщение от справочник
for ([initial-expression]; [condition]; [final-expression])
statement
initial-expression обрабатывается один раз перед началом цикла.

А почему нерабочий - читайте мой пост.
__________________
29375, 35

Последний раз редактировалось Aetae, 01.06.2013 в 08:45.
Ответить с цитированием
  #5 (permalink)  
Старый 01.06.2013, 09:39
Аспирант
Отправить личное сообщение для xintrea Посмотреть профиль Найти все сообщения от xintrea
 
Регистрация: 02.01.2011
Сообщений: 56

Да, не доглядел что там for(), а мне уже везде while() мерещится.

Я впринципе понял, что интерпретатор javascript однопоточный, а реакция на отложенные события сделана через событийную модель. Поэтому блокировать поток ожиданием нельзя, так как обработчики событий обрабатываются между циклами main loop.

В свете этого мне посоветовали пользоваться коллбаками. И инит разбивать на цепочку функций:

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() 
 {
  // Тут инит наконец-то завершен
  ...
 }


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

Получается, что в вышестоящем коде тоже надо делать цепочку вызовов с коллбаками.

А если есть еще выстоящий код (у меня четыре слоя) то и у них у всех тоже придется переделывать на цепочку функций с коллбаковыми вызовами? Я же с ума сойду.
Ответить с цитированием
  #6 (permalink)  
Старый 01.06.2013, 11:28
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,595

Сообщение от xintrea Посмотреть сообщение
А если есть еще выстоящий код (у меня четыре слоя) то и у них у всех тоже придется переделывать на цепочку функций с коллбаковыми вызовами? Я же с ума сойду.
Да да, всё переписать нафиг. С самого начала надо было писать по-другому, но чего уж теперь. Если бы вы дочитали тот мой пост до конца, то обнаружили бы в самом низу работающий пример, показывающий как можно в данном конкретном случае получить желаемый вами результат.
__________________
29375, 35
Ответить с цитированием
  #7 (permalink)  
Старый 01.06.2013, 13:40
Аспирант
Отправить личное сообщение для xintrea Посмотреть профиль Найти все сообщения от xintrea
 
Регистрация: 02.01.2011
Сообщений: 56

Нашел я вашу зарытую собаку, спасибо.

Вопрос: чем чревато использование async: false с вашей точки зрения?
Ответить с цитированием
  #8 (permalink)  
Старый 01.06.2013, 17:18
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,595

Сообщение от xintrea Посмотреть сообщение
Вопрос: чем чревато использование async: false с вашей точки зрения?
В первую очередь, временем ответа сервера случись чего. Если запрос один - таймаут соединения ещё спасёт, а если много то так и будет смотреть юзер на висящую страницу.)
__________________
29375, 35
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как научиться думать на javascript ? samuel Оффтопик 31 03.09.2013 02:10
Как убрать hover? Либо как сделать стрелки статичными? krusty36 Элементы интерфейса 1 13.07.2011 09:20
Как сделать электронный каталог продукции? natarius Серверные языки и технологии 6 24.05.2009 20:56
как сделать гиперсылку на объект javascript??? kos_walker Общие вопросы Javascript 3 30.09.2008 06:58
Сохранение данных на стороне клиента средствами Javascript baal1988 Events/DOM/Window 4 24.08.2008 21:32