Есть ли способ гарантировать, что первый вызов AJAX завершится до того, как будет выполнен следующий вызов? - PullRequest
2 голосов
/ 01 августа 2011

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

Проблема, с которой я сталкиваюсь, заключается в том, что пользовательская информация, похоже, перепутана с пользовательскими событиями.То есть иногда пользователь onfo не меняется для разных ответов, поэтому запланированные события привязываются к неверному пользователю.Если я установлю для свойства AJAX async значение false, все будет хорошо.

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

Есть ли способ гарантировать, что первый вызов JAX завершится до того, как будет выполнен последующий вызов?

(Возможно, мое понимание установки асинхронного на ложное неверно. Не значит ли это, что все данные собраныдо выполнения кода продолжается?)

Вот мой текущий подход:

        //  When page loads
    $(document).ready(function () {
        // Get date range            
        debugger;
    //GetStartDate(), GetEndDate() populates date range
    //PopulateParams() does that for remaining parameters
        $.when(GetStartDate(), GetEndDate())
        .then(function () {
            PopulateParams();
            GetUserSchedule();
        })
        .fail(function () {
            failureAlertMsg();

        })
    });

    // Returns schedule for each person listed in between selected start and end dates
    function GetUserSchedule() {
         for (var i = 0; i < arrRequests.length; i++) {
            $.when(
            // Ajax call to web method, passing in string
            $.ajax({
                type: "POST",
                url: URL/default.aspx/GetSchedules",
                data: arrRequests[i],   // example data: {"UserId":"6115","startDate":"\"7/1/2011\"","endDate":"\"7/31/2011\MoreVals: Vals}                    contentType: "application/json",
                dataType: "json",
                success: SuccessFunction,
                error: function (d) { alert('Failed' + d.responseText + '\nPlease refresh page to try again or contact administrator'); }
            })
            )
            .then(function () {

            }
            );
        }
    }

    // On successful completion of call to web method, paint schedules into HTML table for each user
    function SuccessFunction(data) {            
        if (data != null && data.d != null && data.d.Temp != null) {

        // Calls a bunch of functions to paint schedule onto HTML table
        // Data contains two tables: one contains user info and the other contains rows of info for each event for user
        // at times, the user info is not the correct user or the events are not correct for user
    }

Ответы [ 3 ]

1 голос
/ 01 августа 2011

в $ .ajax ({..

запись:

 $.ajax({
     async: false,
     **rest of code**});
0 голосов
/ 02 августа 2011

Вот как я решил проблему. Надеюсь, это поможет кому-то еще. Там могут быть некоторые опечатки ... это просто для того, чтобы показать общую идею. Я вызвал мой метод GetData рекурсивно:

    //  When page loads
    $(document).ready(function () {
        FunctionToBegin();
    });


    // Populates params and call method containing AJAX call
    function FunctionToBegin() {
        // Populate any required params here, including the first param required for the first AJAX call

        // The following block uses the jQuery.Deferred() object, introduced in jQuery 1.5
        // See http://api.jquery.com/category/deferred-object/
        // the object allows us to chain callbacks, **in the order specified**

        // Get date range
        $.when(GetStartDate(), GetEndDate())
            .then(function () {
      var $trCurrent = $('.DataRow:first');
                //Pass in first userID
                GetData($trCurrent.find('td:first').text().trim()); 
            })
                .fail(function () {
                    failureAlertMsg();
                }
           )
    }


    function GetData(userID) {
        // get the user id
        UserId = userID;
        // Create a json string containing data needed to retrieve the required data
        jsonTextStringified = null;
        jsonTextStringified = JSON.stringify({ UserId: UserId, startDate: startDate, endDate: endDate, AdditionalValues: AdditionalValues });
        // Ajax call to web method, passing in string
        $.ajax({
            type: "POST",
            url: "/URL/default.aspx/WebMethod",
            data: jsonTextStringified,
            contentType: "application/json",
            dataType: "json",
            async: true,
            success: SuccessFunction,
            error: function (d) { alert('Failed' + d.responseText + '\nPlease refresh page to try again or contact administrator'); }
        });
    }

    function SuccessFunction(data) {
      if (data != null && data.d != null && data.d.Temp != null) {
    // Do useful stuff


    // Process next user id
            nextUserID = SomeMethod();
            if (nextUserID != 0) { GetData(nextUserID) }
        }
        else {
                 nextUserID = SomeMethod();
                 if (nextUserID != 0) {  GetData(nextUserID) }
            }
        }
    }

Этот общий план разрешает выполнение каждого асинхронного вызова перед обработкой следующего вызова. Другими словами, группа асинхронных вызовов не выполняется одновременно и, следовательно, не забивает веб-метод, отвечающий за возврат данных. В моем случае я возвращал набор данных, содержащий две таблицы, и возвращенные таблицы были непоследовательно точными, если только я не установил флаг асинхронизации в значение false (неприемлемо для моих целей) или не следовал подходу с разметкой.

0 голосов
/ 01 августа 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...