2009-07-07 3 views
2

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

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.

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

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

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

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

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

ответ

3

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

Как вы узнали, функция 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'); 
        }); 


}; 
+0

Да, спасибо за более ясное разъяснение использования! –

+0

И голосование за потрясающее разъяснение ... –

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 
    } 
} 
+0

Добавлено объяснение вашего предложения кода и способа отображения кода вызова. Надеюсь, ты не против. http://stackoverflow.com/questions/1094716/how-does-one-return-data-to-the-original-caller-function-in-javascript/1095251#1095251 – SolutionYogi

+0

Что делать, если я хочу вернуть ответ на processRequest от ioServer и если более 1 функции вызывают ioServer, поэтому я не уверен в имени функции Requestee ????? – dnxit

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; 
} 

Edit: Хотя это и полезно, это Сорта против зерна «нормального» использования AJAX. Вместо этого я предложил бы изменить ваш подход.

+1

Вы не хотите выполнять синхронный вызов, так как он может заморозить браузер, если запрос ajax не может быть выполнен быстро. – SolutionYogi

+0

@solutionyogi Hah, ya, я был в процессе редактирования, когда вы прокомментировали. Тем не менее, я (прошу прощения) сделал это в прошлом без проблем с замораживанием браузера. Насколько мне известно, JavaScript просто ждет/блокирует и ничего не выполняет. –

1

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

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, как и я.

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

Смежные вопросы