Показ progressbar с запросом ajax

Я хочу показать прогресс с индикатором выполнения jquery ui, когда запускается запрос ajax и когда он заканчивается. Проблема в том, что я не знаю, как устанавливать значения для индикатора выполнения в зависимости от хода выполнения запроса ajax. Здесь код для начала:

function ajaxnews()
    {
        $('.newstabs a').click(function(e){
            var section = $(this).attr('id');
            var url = base + 'news/section/' + section;

            $.ajax({
                url : url,
                dataTye : 'html',
                start : loadNews,
                success : fillNews
            });
        });
    }



// start callback functions
   function loadNews()
   {

       $('#progressbar').fadeIn();
       $('#progressbar').progressbar({ //how shoud I set the values here});
   }

   function fillNews()
   {
    $('#progressbar').progressbar('option', 'value', ?? /* how do I find this?*/);   
    $('#progressbar').fadeOut();
   }

Ответ 1

Основная проблема заключается в том, что вы не знаете, сколько времени займет запрос.

Для индикатора выполнения вам необходимо установить процент или количество выполненных шагов.

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

Если вы можете угадать, сколько времени потребуется, вы можете использовать таймер, чтобы он постепенно увеличивался, скажем, на 90%, автоматически, и когда ответ сервера приходит, установите его на 100%. Конечно, это притворяется совсем немного.

Если у вас есть несколько запросов, вы можете использовать количество заполненных запросов в процентах. Если это имеет смысл, вы можете разбить один запрос на несколько, но внимательно подумайте о том, какое влияние это оказывает на сетевой трафик и время отклика. Не просто делайте это ради индикатора выполнения.

Если запрос действительно занимает много времени, вы можете запустить дополнительные запросы на сервер, чтобы узнать о прогрессе. Но это может означать много работы на стороне сервера.

Извините, но показатели выполнения трудны...

Ответ 2

Я столкнулся с такой ситуацией в нашем собственном приложении. Это было важное приложение, и нам нужно было показать прогресс пользователю. Таким образом, несмотря на то, что @Thilo упомянул о сетевом трафике, нам пришлось реализовать его, чтобы пользователь мог быть проинформирован о завершении долгого процесса и о том, как он прогрессировал с течением времени.

Мы разбили его на мелкие кусочки.

  • Создайте поток на серверном коде для запуска конкретного процесса. Для ASP.Net это было так:

    System.Threading.ThreadPool.QueueUserWorkItem(AddressOf MyProcessRoutine, objectParameter)

  • Внутри этого "MyProcessRoutine" запустите ваш долговременный код и обновите статическую переменную для счетчика или сохраняйте в базе данных, для каждого шага, который вы хотите отслеживать.

  • Создайте еще одну функцию, которая проверяет этот счетчик и возвращает текущее значение. Например: Public Shared Function CheckStatus() As Integer

  • С вашего клиентского кода продолжайте опросить эту рутину каждые 5 секунд (в зависимости от того, сколько сетевого трафика вы можете себе позволить и сколько точности вы хотите. Например: timer = setInterval("MyWebService.CheckStatus();", 500);

  • В своем клиентском коде используйте это возвращаемое значение (счетчик), чтобы обновить индикатор выполнения.

Помимо счетчика, вы также можете вернуть объект, содержащий соответствующие данные, такие как идентификатор записи, чтобы показать пользователю о том, где находится данный процесс.

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

Ответ 3

Я не использую jquery, но это может вам помочь.

Это анимированная панель прогресса Ajax с Fake Fallback.

я просто передаю поддельный размер, зная средний размер моих скриптов

поэтому, если мои скрипты составляют около 50-100 КБ, я устанавливаю поддельный размер до 150 кб.

если вычисленная длина недоступна, я использую фальшивый размер.

в этом script я добавлена ​​дополнительная проверка того, что размер бара всегда меньше контейнера.

просто путем умножения фальшивого размера * 2.. если его меньше, чем загруженные данные.

чтобы все выглядело хорошо, я добавил также эффект перехода css3, чтобы он задерживал 700 мс.

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

скопируйте и вставьте в html файл и проверьте с помощью современного браузера, такого как хром.

замените YOURSITE сайтом контента ajax... или что-то еще.

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Ajax Progress</title>
<style>
#progress{
 width:300px;
 height:20px;
 border:1px solid rgba(0,0,0,0.5);
}
#bar{
 width:0%;
 height:20px;
 background-color:green;
 -webkit-transition:width 700ms ease;   
}
</style>
<script>
var
pb,
fakeSize=100000,//~100kb
progress=function(e){
 fakeSize=(e.loaded>fakeSize?(fakeSize*2):fakeSize);//Bonus
 var tot=(e.lengthComputable?e.total:fakeSize);
 pb.style.width=(100/tot*e.loaded)+'%';
},
onloaded=function(e){
 pb.style.width='100%';
},
ajax=function(a,c){
 c=new XMLHttpRequest;
 c.open('GET',a);
 c.onprogress=progress;
 c.onload=onloaded;
 c.send()
};
window.onload=function(){
 pb=document.getElementById('bar');
 ajax('YOURSITE');
}
</script>
</head>
<body>
<div id="progress"><div id="bar"></div></div>
</body>
</html>

вам просто нужно использовать функцию прогресса в jquery, а затем установить столбец на 100% при загрузке script.

Ответ 4

Изменить: для потомков я оставил свой предыдущий ответ ниже, но, видя, как он на самом деле не отвечает на заданный вопрос, я предоставляю новый ответ.

Некоторые из комментариев по этому вопросу указывают на более новые методы достижения этого. Благодаря HTML5 и новому XHR2 можно поставить обратные вызовы на ход запросов AJAX. Это включает в себя добавление прослушивателей событий к объекту XHR и предоставление обратных вызовов для соответствующих свойств. Эта страница имеет хорошие примеры для загрузки и скачивания и this git repo выглядит хорошо и недавно обновляется.

Кроме того, если вы действительно заинтересованы в рытье в XHR и переопределениях, это сообщение в Mozilla doc должно также помочь, И на самом деле, это сообщение doc похоже на то, о чем я упоминал репо git, о котором я говорил.

Старый ответ: Это старая проблема для людей, которые пишут веб-приложения, а Тило прав, это уже не так сложно, как когда-то. Лучшим решением (imo) является "вырезать" загружаемые файлы и обновлять индикатор выполнения каждый раз, когда вы загружаете кусок. Этот вопрос SO и его ответ - хорошее место, чтобы начать понимать эту концепцию и даже как применить ее к вашей ситуации.

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

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