Вопрос по jquery, ajax, callback, javascript, return – Как вернуть данные в исходную функцию вызывающего абонента в Javascript?

2

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

function ioServer(request_data, callback)
{
    $.ajax({
        cache: false,
        data: "request=" + request_data,
        dataType: "json",
        error: function(XMLHttpRequest, textStatus, errorThrown){},
        success: function(response_data, textStatus){
            callback(response_data);
            },
        timeout: 5000,
        type: "POST",
        url: "/portal/index.php/async"
    });
}   

function processRequest(command, item, properties)
{
    var request = {};
    request.command = command;
    request.item = item;
    request.properties = properties;
    var toServer = JSON.stringify(request); 
    var id = ioServer(toServer, processResponse);
    return id;
}

function processResponse(fromServer)
{
    if (fromServer.response == 1)
    {
        return fromServer.id;   
    }   
}

Я вызываю этот кусок кода, вызывая функцию processRequest внутри другой функции. Отправка запроса и получение ответа работает просто отлично. Однако мне нужно вернуть значение «id». из ответа обратно в функцию processRequest, чтобы он, в свою очередь, мог вернуть это значение вызывающей стороне. Насколько я могу судить, возврат в processResponse возвращается к $ .ajax, но мне нужно, чтобы он возвращался обратно к processRequest.

Кстати, оператор if в processResponse ссылается на значение, установленное серверным PHP-сценарием, чтобы указать, разрешен ли запрос (например, если пользователь не вошел в систему, fromServer.response будет 0). Он не имеет ничего общего с процедурами успеха / ошибки объекта $ .ajax.

Большое спасибо за помощь.

@Jani: Спасибо за ответ, но не могли бы вы уточнить немного? Функция где «идентификатор»; нужен следующий код:

$(#tabs).tabs('add', '#tab-' + id, 'New tab');

Вы говорите, что я должен попытаться выполнить этот кусок кода в функции processResponse? Потому что это не то, что я намеревался сделать; Эти функции предназначены для универсального решения для поддержки состояния на стороне сервера. Вот почему я избегал размещать этот кусок кода там.

Ваш Ответ

5   ответов
3

Поскольку Тони не предоставил никаких комментариев, позвольте мне добавить подробности о том, что он предлагает.

Как вы узнали, функция processRequest завершается, как только выполняется вызов $ .ajax, поскольку метод $ .ajax является асинхронным. Итак, как бы вы уведомили вызывающего процесса processRequest о том, что задача выполнена?

Проще говоря, вы просите, чтобы вызывающий процесс processRequest предоставил «функцию обратного вызова». ProcessRequest будет вызывать эту функцию всякий раз, когда получит вывод AJAX. В коде Тони это последний аргумент функции processRequest.

Итак, ваш код вызова теперь будет выглядеть

function tabMethod()
{
     processRequest('command', 'item', 'properties', 
                  function(id)
                  {
                     if(id == null) 
                     {
                          alert('There is a problem!');
                          return;
                     }
                     $('#tabs').tabs('add', '#tab-' + id, 'New tab');
                  });


};
И голосование за удивительное разъяснение ...
Да, спасибо за более четкое разъяснение использования!
1

Потрясающие! Спасибо ребята за помощь, теперь это работает как шарм. И я научился лучше использовать обратные вызовы. Вот полный рабочий код:

createTab('#tabs'); // I'm using JQuery UI to handle tabs    

function createTab(parent_element){
            var name = {};
            name.name = "New tab";
            var position = {};
            position.position = $(parent_element).tabs('length') + 1;
            var properties = new Array();
            properties[0] = name;
            properties[1] = position;
            processRequest(1, 1, properties, 
                      function(id)
                      {
                         if(id == null) 
                         {
                              alert('There is a problem!');
                              return;
                         }
                         $('#tabs').tabs('add', '#tab-' + id, 'New tab');
                      });
        }

function ioServer(request_data, callback)
{
    $.ajax({
        cache: false,
        data: "request=" + request_data,
        dataType: "json",
        error: function(XMLHttpRequest, textStatus, errorThrown){},
        success: function(response_data, textStatus){
                processResponse(response_data, callback);
                },
        timeout: 5000,
        type: "POST",
        url: "/portal/index.php/async"
    });
}   

function processRequest(command, item, properties, callback)
{
    var request = {};
    request.command = command;
    request.item = item;
    request.properties = properties;
    var toServer = JSON.stringify(request); 
    ioServer(toServer, callback);
}

//internal callback to handle response code
function processResponse(fromServer, callback)
{
    if (fromServer.response == 1)
    {
        //call the callback with the id
        callback(fromServer.id);   
    }   
    else
    {
        //You have to remember to call the callback no matter what
        //or the caller won't know when it's complete
        callback(null);  //or some other "didn't get a valid response" value
    } 
}

И это добавляет новую вкладку в конце списка на странице. Теперь это также хранится на стороне сервера с PHP и MySQL, как я и хотел.

Еще раз спасибо!

0

Вместо того, чтобы реализовывать блокировку для симуляции синхронного вызова, как кто-то ранее опубликовал, просто сделайте сам вызов AJAX синхронным и обновите свою оболочку успеха:

function ioServer(request_data, callback) {
    var response = null;
    $.ajax({
        cache: false,
        data: "request=" + request_data,
        dataType: "json",
        error: function(XMLHttpRequest, textStatus, errorThrown){},
        success: function(response_data, textStatus) {
                response = callback(response_data);
        },
        timeout: 5000,
        type: "POST",
        url: "/portal/index.php/async",
        async: false
    });

    return response;
}

Изменить: Хотя это полезно, это своего рода против зерна "нормальный" AJAX использовать. Я бы предложил вместо этого изменить ваш подход.

@solutionyogi Ха, да, я делал изменения, когда ты это прокомментировал. Однако я (с неохотой) делал это в прошлом без проблем с зависанием браузера. Насколько я знаю, JavaScript просто ждет / блокирует и ничего не выполняет.
Вы не хотите делать синхронный вызов, так как это может привести к зависанию браузера, если ajax-запрос не может быть выполнен быстро.
3

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

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

5

Я думаю, может быть, это ближе к тому, что вы ищете ...

function ioServer(request_data, callback)
{
    $.ajax({
        cache: false,
        data: "request=" + request_data,
        dataType: "json",
        error: function(XMLHttpRequest, textStatus, errorThrown){},
        success: function(response_data, textStatus){
                processResponse(response_data, callback);
                },
        timeout: 5000,
        type: "POST",
        url: "/portal/index.php/async"
    });
}   

function processRequest(command, item, properties, callback)
{
    var request = {};
    request.command = command;
    request.item = item;
    request.properties = properties;
    var toServer = JSON.stringify(request); 
    ioServer(toServer, callback);
}

//internal callback to handle response code
function processResponse(fromServer, callback)
{
    if (fromServer.response == 1)
    {
        //call the callback with the id
        callback(fromServer.id);   
    }   
    else
    {
        //You have to remember to call the callback no matter what
        //or the caller won't know when it's complete
        callback(null);  //or some other "didn't get a valid response" value
    } 
}
Добавлено объяснение вашего кода и как будет выглядеть код вызова. Я надеюсь, что вы не возражаете.stackoverflow.com/questions/1094716/…
Что делать, если я хочу вернуть ответ на processRequest из ioServer и если ioServer вызывает более 1 функции, поэтому я не уверен насчет имени функции Requestee ?????

Похожие вопросы