Редактирование текста с помощью внутреннего текста в цикле for замораживает браузер

#javascript #html #ajax

#язык JavaScript #HTML #аякс

Вопрос:

Я пытаюсь использовать элемент на странице в качестве индикатора прогресса (в процентах). Однако, когда я звоню innerText внутри for цикла, Chrome зависает и не показывает ход выполнения. Вот пример кода (просто чтобы продемонстрировать проблему):

 lt;!DOCTYPE htmlgt; lt;htmlgt; lt;headgt;  lt;titlegt;Hellolt;/titlegt;  lt;meta charset="utf-8"/gt;  lt;script src="https://code.jquery.com/jquery-3.6.0.min.js"gt;lt;/scriptgt; lt;/headgt; lt;bodygt;  lt;h1 id="a"gt;Hello!lt;/h1gt; lt;/bodygt; lt;script type="text/javascript"gt;  function initTrs(){  for(var i = 1; ilt;=100; i  ){  document.getElementById("a").innerText = i;  $.ajax({  url: "https://www.google.com",  async: false,  done: function (a) {}  });  }  }  window.addEventListener("load", () =gt; initTrs()); lt;/scriptgt; lt;/htmlgt;  

Firefox работает с ним нормально; однако Chrome зависает до тех пор, пока for цикл не будет полностью завершен.

Кто-нибудь может мне в этом помочь? Спасибо!

Комментарии:

1. Вы указали, что вызов AJAX должен быть синхронным, Chrome рассматривает его как блокировку в цикле событий и, таким образом, ожидает завершения цикла перед обновлением innerText . Почему ты делаешь этот синхронный звонок?

2. Мне действительно интересно, почему это сработает в FF. Потому что во время работы JS визуализация DOM обычно блокируется. И заставляя ваш ajax вызов действовать синхронно, вы не позволяете браузеру выполнять рендеринг …

3. @BenM требуется, чтобы мой API работал должным образом. Есть ли способ оптимизировать его без одновременного выполнения большого количества запросов?

4. @RodionGrinberg Почему ваш API заботит, выполняются ли к нему вызовы синхронно или асинхронно?

5. сделайте вызов ajax асинхронным и ожидайте его, а также сделайте асинхронными initTrs, чтобы иметь возможность использовать в нем ожидание.

Ответ №1:

Вот как я решил эту проблему в конце:

 lt;!DOCTYPE htmlgt; lt;htmlgt; lt;headgt;  lt;titlegt;Hellolt;/titlegt;  lt;meta charset="utf-8"/gt;  lt;script src="https://code.jquery.com/jquery-3.6.0.min.js"gt;lt;/scriptgt; lt;/headgt; lt;bodygt;  lt;h1 id="a"gt;Hello!lt;/h1gt; lt;/bodygt; lt;script type="text/javascript"gt;  function initTrs(){  for(var i = 1; ilt;=100; i  ){  const iter = i;  setTimeout(() =gt; {  document.getElementById("a").innerText = iter;  $.ajax({  url: "https://www.google.com",  async: false,  done: function (a) {}  });  });  }  }  window.addEventListener("load", () =gt; initTrs()); lt;/scriptgt; lt;/htmlgt;  

Комментарии:

1. поскольку вы не установили интервал времени в setTimeout , он будет иметь тайм-аут 0, и у вас будет 100 параллельных (асинхронных) запросов. Если с вашим api все в порядке, он вам вообще не нужен setTimeout