Функция обратного вызова jQuery getJSON не обновляет DOM, пока не завершит работу - PullRequest
0 голосов
/ 21 сентября 2011

У меня есть индикатор выполнения jQuery ui

var item = 4;

$('<div/>', { id: 'progressBar' + item, 'class': 'ui-widget-default flpb' }).appendTo($('#test'));
$('#progressBar' + item).progressbar({ value: 0 });

здесь индикатор выполнения отображается на странице

, затем я выполняю ajax-вызов, подобный этому

$.getJSON("http://" + jsonServiceUrl + "/data/for/" + item + "/from/" + $('#dtStart').val() + "/to/" + $('#dtEnd').val() + "?callback=?", 
   function (results) {
       var pbScale = 100 / results.count,
           startTime = new Date().getTime();

       $.each(result, function (r, result) {
           //here the progress bar doesn't update.
           $('<div/>', { html: " Date: " + new Date(parseInt(result.TimeOfMeasurement.substr(6))) }).appendTo('#test');
           $('#progressBar' + item).progressbar('value', r * pbScale);
       });
       console.debug('elapsed milisecs: ' + new Date().getTime() - startTime;
   });

ProgressBar получает обновления «100%» после завершения функции обратного вызова.

РЕДАКТИРОВАТЬ:

Я не пытаюсь получить прогресс моего вызова JSON, я 'Я пытаюсь добиться прогресса в цикле сбора вещей, которые я получаю с сервера.Помимо обновления индикатора выполнения я также рисую элемент div для каждого элемента коллекции.В коллекции содержится до 200 элементов, поэтому для их отображения достаточно прогресса.

Рядом с индикатором выполнения, который не обновляется, вновь созданные элементы div также не отображаются, пока не завершится функция обратного вызова.

Я добавил таймер, и время обработки составляет около 1000 миллисекунд (этого должно быть достаточно для обновления индикатора выполнения пары элементов).

Ответы [ 2 ]

0 голосов
/ 21 сентября 2011

$.each - это синхронный вызов, который эквивалентен циклу for(;;;). Итерация по вашему results происходит мгновенно, и хотя индикатор будет обновляться в фоновом режиме, вы слишком быстро заметите это.

Вы хотите показывать ход выполнения вашего запроса AJAX, а не ход выполнения итерации по набору результатов. Кроме того, поскольку $.each является синхронным, если он когда-либо станет достаточно большим, чтобы гарантировать для него индикатор выполнения, у вас будут большие проблемы, о которых нужно беспокоиться; например, неотзывчивость вашего приложения до завершения итерации, чем отображение индикатора выполнения.

0 голосов
/ 21 сентября 2011

Функция обратного вызова срабатывает только при успешном вызове.

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

Второй способ - сделать что-то с сокетами и передать ваши данные с сервера на ваш компьютер. Я сомневаюсь, что вы можете сделать что-то подобное с обычным jquery, вам понадобится хотя бы какой-нибудь плагин, и ваш код на стороне сервера также потребуетсяподдержать это.для получения дополнительной информации взгляните на socket.io и

...