Definicja funkcji zwrotnej jQuery ajax sukcesu

90

Chcę używać jQuery ajax do pobierania danych z serwera.

Chcę umieścić definicję funkcji wywołania zwrotnego sukcesu poza .ajax()blokiem, jak poniżej. Czy muszę więc zadeklarować zmienną dataFromServerpodobną do poniższej, aby móc użyć danych zwróconych z wywołania zwrotnego sukcesu?

Widziałem, jak większość ludzi definiuje wywołanie zwrotne sukcesu wewnątrz .ajax()bloku. Czy więc poniższy kod jest poprawny, jeśli chcę zdefiniować wywołanie zwrotne sukcesu na zewnątrz?

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
}
tonga
źródło

Odpowiedzi:

93

Po prostu użyj:

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

successWłaściwość wymaga jedynie odniesienie do różnych funkcji, i przekazuje te dane jako parametr do tej funkcji.

Możesz uzyskać dostęp do swojej handleDatafunkcji w ten sposób, ponieważ sposób handleDatajest zadeklarowany. JavaScript przeanalizuje Twój kod pod kątem deklaracji funkcji przed jego uruchomieniem, dzięki czemu będziesz mógł użyć funkcji w kodzie, który jest przed rzeczywistą deklaracją. Nazywa się to podnoszeniem .

Nie dotyczy to jednak funkcji zadeklarowanych w ten sposób:

var myfunction = function(){}

Są one dostępne tylko wtedy, gdy tłumacz je zdał.

Zobacz to pytanie, aby uzyskać więcej informacji na temat 2 sposobów deklarowania funkcji

Cerbrus
źródło
1
@Alnitak, kiedy to zostało deferred objectswprowadzone? Nie widziałem tego wcześniej. Wydaje się też nieco kłopotliwe, ponieważ kod definiujący wywołanie zwrotne do użycia znajduje się w innej lokalizacji niż rzeczywiste wywołanie AJAX.
Cerbrus,
4
został wprowadzony w jQuery 1.5 i jest znacznie mniej kłopotliwy niż używanie success:. Odłączenie wywołania zwrotnego od AJAX to dobra rzecz! Zobacz notatki, które właśnie dodałem na końcu mojej odpowiedzi.
Alnitak
@Alnitak, spojrzę. Zobaczmy, czy uda mi się przekonać: P
Cerbrus,
@Alnitak: Czy odroczone obiekty są zawsze preferowane przed wywołaniem zwrotnym sukcesu? Dzięki.
tonga
@tonga IMHO, tak, bardzo preferowane. Gdyby twój kod używał $.get()na przykład, byłoby niemożliwe dodanie error:modułu obsługi, ponieważ $.getgo nie obsługuje. Jakkolwiek można dodać .faildo odroczonego wyniku z $.get.
Alnitak
199

„Nowym” sposobem zrobienia tego od czasu jQuery 1.5 (styczeń 2011) jest użycie obiektów odroczonych zamiast przekazywania successwywołania zwrotnego. Powinieneś zwrócić wynik, $.ajaxa następnie użyć metod .done, .failetc, aby dodać wywołania zwrotne poza $.ajaxwywołaniem .

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

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

getData().done(handleData);

To oddziela obsługę wywołań zwrotnych od obsługi AJAX, pozwala na dodawanie wielu wywołań zwrotnych, wywołań zwrotnych po awarii itp., A wszystko to bez konieczności modyfikowania oryginalnej getData()funkcji. Oddzielenie funkcjonalności AJAX od zestawu czynności do późniejszego wykonania to dobra rzecz!.

Odroczenia pozwalają również na znacznie łatwiejszą synchronizację wielu zdarzeń asynchronicznych, których nie można łatwo zrobić po prostu success:

Na przykład mógłbym dodać wiele wywołań zwrotnych, moduł obsługi błędów i poczekać, aż upłynie czas, zanim przejdę dalej:

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

Inne części jQuery również używają obiektów odroczonych - możesz bardzo łatwo zsynchronizować animacje jQuery z innymi operacjami asynchronicznymi.

Alnitak
źródło
1
@Cerbrus zobacz nowy przykład, a następnie zastanów się, jak to zrobić bez obiektów odroczonych
Alnitak,
Obiekty odroczone @jbl są fantastyczne. I normalnie downvote żadnej odpowiedzi, która promuje wykorzystanie success:ponieważ deferreds prostu pracować o wiele lepiej.
Alnitak
@Cerbrus dokładnie tak to powinno być interpretowane. Proponuję szukać tutaj user:6782 deferredo wiele więcej przykładów.
Alnitak
Jak można to wykorzystać w przypadku zdarzenia przesyłania formularza?
haakym
To alertjednak… Osobiście użyłbym console.log(data)lub jeśli jest to tablica: console.table(data):)
Armstrongest
16

Nie wiem, dlaczego definiujesz parametr poza skryptem. To jest niepotrzebne. Twoja funkcja zwrotna zostanie wywołana automatycznie ze zwracanymi danymi jako parametrem. Jest bardzo możliwe zdefiniowanie twojego wywołania zwrotnego poza sucess:ie

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

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

zostanie wywołana funkcja handleData i parametr przekazany do niej przez funkcję Ajax.

BinaryTox1n
źródło
6

Spróbuj przepisać swój program obsługi sukcesu na:

success : handleData

Właściwość sukcesu metody Ajax wymaga jedynie odwołania do funkcji.

W swojej funkcji handleData możesz przyjąć do 3 parametrów:

object data
string textStatus
jqXHR jqXHR
Nieokreślony
źródło
5

Napisałbym :

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


function getData() {
    $.ajax({
        url : 'example.com',
        type: 'GET',
        success : handleData
    })
}
jbl
źródło
15
Twój kod nigdy nie używa, dataFromServerwięc pierwsza linia może zostać usunięta.
Anthony Grist
2

Nie musisz deklarować zmiennej. Funkcja sukcesu Ajax automatycznie przyjmuje do 3 parametrów:Function( Object data, String textStatus, jqXHR jqXHR )

Lukas Bijaminas
źródło
Musiałem jakoś chwilę szukać, aby znaleźć te domyślne parametry. Dzięki!
płatność
2

po kilku godzinach baw się nim i prawie się nudzą. cud przyszedł do mnie, to działa.

<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>
Võ Minh
źródło
1
nie musisz umieszczać innego wywołania funkcji, aby osiągnąć sukces. możesz bezpośrednio powiedzieć, że success : callbackjquery uruchomi twoją funkcję wywołaną callbackz dataparametrem w niej zawartym.
Olgun Kaya,
-1

W twoim komponencie tj. Kątowy kod JS:

function getData(){
    window.location.href = 'http://localhost:1036/api/Employee/GetExcelData';
}
Shivani Jadhav
źródło