Может ли одна и та же функция js одновременно выполнять вызовы AJAX?

#javascript #ajax #jquery

#javascript #ajax #jquery

Вопрос:

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

Вызов выполняет svn, поэтому это может занять даже минуту или около того. Я могу заметить, что если я инициирую новый вызов AJAX до завершения предыдущего, я теряю результат вызова.

Есть ли какой-либо способ запустить несколько вызовов AJAX одновременно, получить результаты вызова и отобразить их?

  • использование jQuery
  • в том же окне браузера
  • вызов php

HTML-код, вызывающий javascript

     <button type="button" onclick="update_revision('' . $directory  . '',''.$server_name.'')" > update </button>
  

Javascript

    function update_revision(revision,server_name)
    {
      if (window.XMLHttpRequest)
        {// code for IE7 , Firefox, Chrome, Opera, Safari
        xmlhttp=new XMLHttpRequest();
        }
      else
        {// code for IE6, IE5
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
        }
      xmlhttp.onreadystatechange=function()
        {
        if (xmlhttp.readyState==4 amp;amp; xmlhttp.status==200)
          {
          document.getElementById("rev." revision).value="updated to " update_to;
          }
        }
      xmlhttp.open("GET","https://" server_name "/imacs/radek/svn_update.php?code_base=" revision "amp;revision=" update_to "amp;t="   Math.random(),true);
      xmlhttp.send();
    }        
  

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

1. Просто прекратите использовать глобальные переменные. Вы перезаписываете, xmlhttp поэтому каждый раз, когда изменяется состояние любого из ваших объектов XHR, onreadystatechange проверяется состояние последнего созданного вами объекта.

2. @Quentin: не могли бы вы подробнее рассказать? Я не понимаю…

Ответ №1:

Проблема в том, что вы используете одну глобальную переменную для хранения всех ваших экземпляров XMLHttpRequest. Всякий раз, когда вы создаете новый экземпляр и сохраняете ссылку на него в глобальной переменной, xmlhttp экземпляр, на который там была ранее ссылка, становится без ссылок, и поэтому он будет собран как только браузер сочтет нужным. Обычно это означает, что мусор собирается немедленно; и в вашем случае он собирается как мусор еще до получения ожидающего ответа.

Один из способов решить эту проблему — объявить xmlhttp как локальный var в вашей update_revision() функции. Вот так:

 function update_revision(revision, server_name) {
    // declare xmlhttp locally
    var xmlhttp;  

    if (window.XMLHttpRequest) { // code for IE7 , Firefox, Chrome, Opera, Safari
        xmlhttp = new XMLHttpRequest();
    }
    else { // code for IE6, IE5
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4 ) {
            if( xmlhttp.status == 200) {
                document.getElementById("rev."   revision).value = "updated to "   update_to;
            }

            // explicitly drop the reference when
            // we're done with it, so the browser will reclaim the object
            // (this is optional, but it's a good idea)
            xmlhttp = null;
        }
    }
    xmlhttp.open("GET", "https://"   server_name   "/imacs/radek/svn_update.php?code_base="   revision   "amp;revision="   update_to   "amp;t="   Math.random(), true);
    xmlhttp.send();
}
  

Примечания:

  1. xmlhttp объявляется как локальный var

  2. xmlhttp «обнуляется», когда нам это больше не нужно (после readyState == 4). Это приведет к тому, что браузер соберет мусор для экземпляра запроса, тем самым предотвращая утечку ресурсов. Это хорошая практика (и поэтому я показал это в примере выше), но технически это необязательно.

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

1. Отличное объяснение. Нееет, я понял. Что, если я использую jQuery вместо чистого javascript?