2010-08-21 2 views
5

Предполагается вернуть объект JSON, содержащий список имен файлов изображений. Прокомментированное предупреждение показывает правильные данные, но alert(getPicsInFolder("testfolder")); показывает "error".Не удается получить правильное возвращаемое значение из вызова jQuery Ajax

function getPicsInFolder(folder) { 
    return_data = "error"; 
    $.get("getpics.php?folder=" + folder, function (data) { 
    data = jQuery.parseJSON(data); 
    $.each(data, function (index, value) { 
     data[index] = "folders/" + folder + "/" + value; 
    }); 
    //alert(data); // This alert shows the correct data, but that's hardly helpful 
    return_data = data; 
    }); 
    return return_data; 
} 

Что я делаю неправильно?

ответ

10

Вы вызываете асинхронный метод $.get(), где функция обратного вызова будет вызвана после возвращения функции getPicsInFolder(). Следуйте комментарии в приведенном ниже примере:

function getPicsInFolder(folder) { 
    return_data = "error"; 
    // Since the $.get() method is using the asynchronous XMLHttpRequest, it 
    // will not block execution, and will return immediately after it is called, 
    // without waiting for the server to respond. 
    $.get("getpics.php", function (data) { 
     // The code here will be executed only when the server returns 
     // a response to the "getpics.php" request. This may happen several 
     // milliseconds after $.get() is called. 
     return_data = data; 
    }); 

    // This part will be reached before the server responds to the asynchronous 
    // request above. Therefore the getPicsInFolder() function returns "error". 
    return return_data; 
} 

Вы должны рассмотреть рефакторинга кода таким образом, что логика для обработки объекта JSON находится в $.get() обратного вызова. Пример:

$.get("getpics.php?folder=test", function (data) { 
    // Handle your JSON data in here, or call a helper function that 
    // can handle it: 
    handleMyJSON(data); // your helper function 
}); 
+0

Спасибо. Ясно, что мне нужно переосмыслить и переписать это. – Dataflashsabot

3

Вы получаете данные асинхронно. Функция обратного вызова function (data) {} вызывается после возврата getPicsInFolder.

У вас есть два варианта:

  1. (плохой вариант): установите ваш АЯКС вызов синхронными.

  2. (правый вариант): перестройте свой код, чтобы в обратном вызове произошло что-либо, что должно произойти с возвращаемыми данными.

Один из способов сделать это было бы передать функцию обратного вызова в getPicsInFolder, как это:

function getPicsInFolder(folder, callback) { 
    return_data = "error"; 
    $.get("getpics.php?folder=" + folder, function (data) { 
     data = jQuery.parseJSON(data); 
     $.each(data, function (index, value) { 
      data[index] = "folders/" + folder + "/" + value; 
     }); 
    callback(data); //pass data into the callback function 
}); 

Затем, когда вы называете getPicsInFolder, вместо того, чтобы делать:

pics = getPicsInFolder('foldername'); 
//do something with pics 

сделать это:

getPicsInFolder('foldername', function (pics) { 
    //do something with pics 
}); 
0

Вы смущены тем, как работает AJAX. Данные недоступны до тех пор, пока запрос не завершится, что произойдет после того, как функция вернулась. И данные доступны только в обратном вызове.

1

Запросы AJAX должны быть асинхронными (вы : могут выполнять синхронные за счет остановки исполнения и фактически блокирования вашего пользовательского интерфейса).

getPicsInFolder() возвращается до завершения запроса AJAX. Вам необходимо обновить вам UI/обрабатывать объект JSON возвращается на полное событие (анонимной функции вы передаете в качестве аргумента $.get()):

$.get("", function() 
{ 
    // This anonymous function will execute once the request has been completed 

    // Update your UI/handle your data here 
}); 

Скажите, что я хотел, чтобы обновить элемент в моем UI ...

$("#ID-of-a-button-in-the-UI").click(function() // executes on click 
{ 
    $.get("url-to-JSON-object", function (json) // executes on request complete 
    { 
     $("#ID-of-element-to-update").html(json.rows[0].key); // updates UI 
    }); 
}); 
+0

Вы можете запросить синхронизацию XHR. – strager

+0

@stranger: Это правда, вы можете, но синхронный XHR не может быть AJAX по определению, так как A в AJAX для асинхронного :) –

+0

Обновлен мой ответ. – roosteronacid

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