Синхронный AJAX…Я знаю, это звучит безумно

#javascript #ajax

#javascript #ajax

Вопрос:

У меня есть веб-методы, которые вызываются через AJAX в веб-приложении .Net 4.0. Во многих случаях вызовы AJAX выполняются повторно в цикле for . Моя проблема в том, что информация, которую веб-метод синхронизирует с моим сервером, имеет временную метку и поэтому должна синхронизироваться в том порядке, в котором я отправляю ее в AJAX. К сожалению, кажется, что все, что заканчивается первым, просто заканчивается первым, и все временные метки не в порядке. Мне нужно в основном ставить в очередь мои запросы AJAX, чтобы они выполнялись по порядку, а не асинхронно, что, как я знаю, является A в AJAX, так что это может быть совершенно глупый вопрос.

Как мне принудительно изменить порядок выполнения для вызовов AJAX, выполняемых в цикле for?

Редактировать: некоторый код

                     for (var i = 0; i < itemCnt - 1; i  ) {

                    try {
                        key = items[i];
                        item = localStorage.getItem(key);
                        vals = item.split(",");
                        type = getType(key);


                        if (type == "Status") {
                            var Call = key.substring(7, 17);
                            var OldStat = vals[0];
                            var NewStat = vals[1];
                            var Date1 = vals[2];
                            var Time1 = vals[3];
                            var miles = vals[4];

                            try {
                                stat(Call, OldStat, NewStat, Date1, Time1, miles, key);

                            }
                            catch (e) {
                                alert("Status "   e);
                                return;
                            }

                        }
                        else if (type == "Notes") {
                            var Call = key.substring(6, 16);
                            var Notes = item;
                            try {
                                addNotes(Call, Notes);
                            }
                            catch (e) {
                                alert("Notes "   e);
                                return;
                            }
                        }
                        else if (key == "StartNCTime" || key == "EndNCTime") {
                            var TechID = vals[0];
                            var Date = vals[1];
                            var Time = vals[2];
                            var Activity = vals[3];
                            var Location = vals[4];
                            var Type = vals[5];

                            try {
                                logTime(TechID, Date, Time, Activity, Location, Type, 
                            }
                            catch (e) {
                                alert(key   ' '   e);
                                return;
                            }

                        }
                    }
                    catch (e) {
                        alert(key   ' '   e);
                        return;
                    }
                }

function stat(Call, OldStat, NewStat, Date1, Time1, miles, key) {
$.ajax({
    type: "POST",
    dataType: "json",
    contentType: "application/json",
    url: "Service.asmx/update_Stat",
    data: '{ CallNumber:"'   Call   '", OldStat:"'   OldStat   '", NewStat:"'   NewStat   '", Date1:"'   Date1   '", Time1:"'   Time1   '", Miles: "'   miles   '"}',
    success: function (data) { },
    error: function (xhr, status, error) {
        var err = eval("("   xhr.responseText   ")");
        alert("Sync Update Stat: "   err.Message);
        location = location;
    }
});
}

function logTime(TechID, Date, Time, Activity, Location, Type, key) {
$.ajax({
    type: "POST",
    dataType: "json",
    contentType: "application/json",
    url: "Service.asmx/nonCallTime",
    data: '{ TechID:"'   TechID   '", Date1:"'   Date   '", Time1:"'   Time   '", Activity:"'   Activity   '", Location:"'   Location   '", Type: "'   Type   '"}',
    success: function (data) { },
    error: function (xhr, status, error) {
        var err = eval("("   xhr.responseText   ")");
        alert("Sync Non Call Time: "   err.Message);
        location = location;
    }
});
}

function addNotes(Call, Notes) {
$.ajax({
    type: "POST",
    dataType: "json",
    contentType: "application/json",
    url: "Service.asmx/addNote",
    data: '{ Call:"'   Call   '", Notes:"'   Notes   '"}',
    success: function (data) { },
    error: function (xhr, status, error) {
        var err = eval("("   xhr.responseText   ")");
        alert("Sync Notes: "   err.Message);
        location = location;
    }
});
  

}

Ответ №1:

Вы должны использовать обратные вызовы.

 function ajax1(){
   //..some code
   //on ajax success:
   ajax2();
}

//etcetera...
  

Или я мог бы предложить использовать библиотеку javascript, например jQuery , для синхронизации ваших запросов ajax для вас.

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

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

2. Вы упомянули использование jQuery для синхронизации. Как это может выглядеть? Извините, я на 100% самоучка. 🙂

Ответ №2:

установите для третьего параметра в методе open объекта xmlhttp значение false, чтобы сделать его синхронным.

http://www.w3schools.com/ajax/ajax_xmlhttprequest_send.asp

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

1. @Raynos это было просто для того, чтобы сообщить OP о существовании синхронного ajax, прочитайте название вопроса. Однако я бы не обязательно использовал это. Что плохого в том, чтобы говорить людям, что он существует, независимо от того, хорошо это или плохо? Я бы предпочел сохранить все ответы и обработать их в соответствии с меткой времени после получения всех ответов.

2. Проблема в том, что вы продвигаете плохие практики, даже не упоминая, что это плохая практика.

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

4. Правильно, но ajax — не лучшая практика. Это единственная практика. sjax — это просто глупый и грязный хак, который никогда не следует использовать.

Ответ №3:

Общий шаблон для последовательного выполнения действий был бы таким:

 function doAjax(data, cb) {
  ...
  // when ready call cb
}

(function (next) {
  var xhr = doAjax(data, next);
})(function (next) {
  var xhr = doAjax(data, next);
})(function (next) {
  doAjax(data);
});
  

Выполнение этого в цикле for потребует рекурсии.

 (function next() {
  if ( i < n ) {
    doAjax(data[i  ], next);
  }
})();