Визначення функції зворотного виклику jQuery ajax


90

Я хочу використовувати jQuery ajax для отримання даних із сервера.

Я хочу помістити визначення функції зворотного виклику за межі .ajax()блоку, як показано нижче. Тож чи потрібно мені оголошувати змінну, dataFromServerяк показано нижче, щоб я міг використовувати повернені дані із зворотного виклику успіху?

Я бачив, як більшість людей визначають зворотний виклик успіху всередині .ajax()блоку. Тож чи правильний наступний код, якщо я хочу визначити зворотний виклик успіху зовні?

var dataFromServer;  //declare the variable first

function getData() {
    $.ajax({
        url : 'example.com',
        type: 'GET',
        success : handleData(dataFromServer)
    })
}

function handleData(data) {
    alert(data);
    //do some stuff
}

Відповіді:


93

Просто використовуйте:

function getData() {
    $.ajax({
        url : 'example.com',
        type: 'GET',
        success : handleData
    })
}

successВластивість вимагає тільки посилання на функцію, і передає дані в якості параметра цієї функції.

Ви можете отримати доступ до своєї handleDataфункції таким чином через спосіб handleDataоголошення. JavaScript буде аналізувати ваш код для оголошень функцій перед його запуском, тому ви зможете використовувати функцію в коді, що перед фактичним оголошенням. Це відоме як підйом .

Однак це не враховується для функцій, оголошених таким чином:

var myfunction = function(){}

Вони доступні лише тоді, коли їх перекладач передав.

Дивіться це питання, щоб отримати додаткову інформацію про 2 способи оголошення функцій


1
@Alnitak, коли ця deferred objectsріч була представлена? Я раніше цього не бачив. Крім того, це здається трохи безладним, оскільки код, який визначає, який зворотний виклик використовувати, знаходиться в іншому місці, ніж фактичний виклик AJAX.
Cerbrus

4
він був введений в jQuery 1.5, і він набагато менш безладний, ніж використання success:. Від’єднання зворотного виклику від AJAX - це добре ! Див. Примітки, які я щойно додав, у кінець моєї відповіді.
Alnitak

@Alnitak, я подивлюсь. Подивимось, чи можу я переконатись: P
Сербрус

@Alnitak: Чи завжди відкладені об'єкти надають перевагу над успішним зворотним викликом? Дякую.
tonga

@tonga IMHO, так, дуже переважно. Якби ваш код використовував, $.get()наприклад, було б неможливо додати error:обробник, оскільки $.getвін не підтримує його. Однак ви можете додати .failдо відстроченого результату з $.get.
Alnitak

199

"Новим" способом зробити це з jQuery 1.5 (січень 2011 р.) Є використання відкладених об'єктів замість передачі successзворотного виклику. Ви повинні повернути результат , $.ajaxа потім використовувати .done, і .failт.д. методи для додавання зворотних викликів поза $.ajaxвиклику .

function getData() {
    return $.ajax({
        url : 'example.com',
        type: 'GET'
    });
}

function handleData(data /* , textStatus, jqXHR */ ) {
    alert(data);
    //do some stuff
}

getData().done(handleData);

Це відокремлює обробку зворотного виклику від обробки AJAX, дозволяє додавати декілька зворотних викликів, зворотних викликів тощо, і все це без необхідності модифікувати початкову getData()функцію. Відокремлення функціональності AJAX від набору дій, які потрібно виконати згодом, - це добре! .

Відкладені також дозволяють набагато легше синхронізувати безліч асинхронних подій, з якими ви не можете легко обійтися success:

Наприклад, я міг додати кілька зворотних викликів, обробник помилок і почекати, поки таймер закінчиться, перш ніж продовжувати:

// a trivial timer, just for demo purposes -
// it resolves itself after 5 seconds
var timer = $.Deferred();
setTimeout(timer.resolve, 5000);

// add a done handler _and_ an `error:` handler, even though `getData`
// didn't directly expose that functionality
var ajax = getData().done(handleData).fail(error);

$.when(timer, ajax).done(function() {
    // this won't be called until *both* the AJAX and the 5s timer have finished
});

ajax.done(function(data) {
    // you can add additional callbacks too, even if the AJAX call
    // already finished
});

Інші частини jQuery також використовують відкладені об'єкти - ви можете дуже легко синхронізувати анімацію jQuery з іншими асинхронними операціями.


1
@Cerbrus подивіться на новий приклад, а потім подумайте, як би ви це зробили без відкладених об'єктів
Alnitak

Відкладені об'єкти @jbl - це фантастика. Я зазвичай прихиляюсь до будь-якої відповіді, яка сприяє використанню, success:оскільки відкладені просто працюють набагато краще.
Alnitak

@Cerbrus саме так його слід інтерпретувати. Запропонуйте вам шукати тут user:6782 deferredще багато прикладів.
Alnitak

Як можна використати це за допомогою подання форми?
haakym

Це alertхоч ... я б особисто використовував console.log(data)або якщо це масив: console.table(data):)
Armstrongest

16

Я не знаю, чому ви визначаєте параметр поза сценарієм. Це непотрібно. Ваша функція зворотного дзвінка буде автоматично викликана з даними повернення як параметром. Дуже можливо визначити зворотний виклик за межами sucess:тобто

function getData() {
    $.ajax({
        url : 'example.com',
        type: 'GET',
        success : handleData
    })
}

function handleData(data) {
    alert(data);
    //do some stuff
}

буде викликана функція handleData і параметр, переданий їй функцією ajax.


6

Спробуйте переписати свій обробник успіху на:

success : handleData

Властивість успіху методу ajax вимагає лише посилання на функцію.

У вашій функції handleData ви можете взяти до 3 параметрів:

object data
string textStatus
jqXHR jqXHR

5

Я б написав:

var handleData = function (data) {
    alert(data);
    //do some stuff
}


function getData() {
    $.ajax({
        url : 'example.com',
        type: 'GET',
        success : handleData
    })
}

15
Ваш код насправді ніколи не використовує, dataFromServerщоб можна було видалити перший рядок.
Anthony Grist

2

Вам не потрібно оголошувати змінну. Функція успіху Ajax автоматично приймає до 3 параметрів:Function( Object data, String textStatus, jqXHR jqXHR )


Якось довелося шукати якийсь час, щоб знайти ці параметри за замовчуванням. Дякую!
payne

2

через кілька годин пограйте з нею і ледь не затупіть. диво прийшло до мене, це спрацювало.

<pre>


var listname = [];   


 $.ajax({
    url : wedding, // change to your local url, this not work with absolute url
    success: function (data) {
       callback(data);
    }
});

function callback(data) {
      $(data).find("a").attr("href", function (i, val) {
            if( val.match(/\.(jpe?g|png|gif)$/) ) { 
             //   $('#displayImage1').append( "<img src='" + wedding + val +"'>" );
                 listname.push(val);
            } 
        });
}

function myfunction() {

alert (listname);

}

</pre>

1
вам не потрібно робити ще один виклик функції для успіху. Ви можете прямо сказати, що success : callbackjquery активує вашу функцію, що викликається callbackіз dataпараметром у ній.
Олгун Кая

-1

У вашому компоненті, тобто кутовому коді JS:

function getData(){
    window.location.href = 'http://localhost:1036/api/Employee/GetExcelData';
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.