jQuery: Return data after ajax call success [duplicate]

To pytanie ma już odpowiedź tutaj:

Mam coś takiego, gdzie jest to proste wywołanie skryptu, które zwraca mi wartość, ciąg znaków..

function testAjax() {
    $.ajax({
      url: "getvalue.php",  
      success: function(data) {
         return data; 
      }
   });
}

Ale jeśli nazwę coś takiego

var output = testAjax(svar);  // output will be undefined...

Więc jak Mogę zwrócić wartość? poniższy kod robi chyba też nie działa...

function testAjax() {
    $.ajax({
      url: "getvalue.php",  
      success: function(data) {

      }
   });
   return data; 
}
Author: Hakam Fostok, 2011-03-15

5 answers

Jedynym sposobem na zwrócenie danych z funkcji byłoby wykonanie połączenia synchronicznego zamiast asynchronicznego, ale to zawiesiłoby przeglądarkę, czekając na odpowiedź.

Możesz przekazać funkcję zwrotną, która obsługuje wynik:

function testAjax(handleData) {
  $.ajax({
    url:"getvalue.php",  
    success:function(data) {
      handleData(data); 
    }
  });
}

Nazwij to tak:

testAjax(function(output){
  // here you use the output
});
// Note: the call won't wait for the result,
// so it will continue with the code here while waiting.
 335
Author: Guffa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-15 19:13:39

Uwaga: Ta odpowiedź została napisana w lutym 2010.
Zobacz aktualizacje z 2015, 2016 i 2017 na dole.

Nie można zwracać niczego z funkcji asynchronicznej. To co możesz zwrócić to obietnica . Wyjaśniłem, jak obietnice działają w jQuery w moich odpowiedziach na te pytania: {]}

Jeśli mógłbyś wyjaśnić dlaczego chcesz zwrócić Dane i co chcesz z nimi później zrobić, to może będę w stanie dać ci bardziej szczegółową odpowiedź, jak to zrobić.

Ogólnie, zamiast:

function testAjax() {
  $.ajax({
    url: "getvalue.php",  
    success: function(data) {
      return data; 
    }
  });
}

Możesz napisać swoją funkcję testAjax tak:

function testAjax() {
  return $.ajax({
      url: "getvalue.php"
  });
}

Wtedy możesz otrzymać swoją obietnicę w ten sposób:

var promise = testAjax();

Możesz zapisać swoją obietnicę, możesz ją przekazać, możesz użyć jej jako argumentu w wywołaniach funkcji i możesz zwrócić je z funkcji, ale kiedy w końcu chcesz użyć Twoich danych, które są zwracane przez wywołanie AJAX, musisz to zrobić w następujący sposób:

promise.success(function (data) {
  alert(data);
});

(zobacz aktualizacje poniżej, aby zapoznać się z uproszczoną składnią.)

Jeśli dane są dostępne w tym momencie, Ta funkcja zostanie wywołana natychmiast. Jeśli tak nie jest, zostanie wywołany, gdy tylko dane będą dostępne.

Cały sens robienia tego wszystkiego polega na tym, że Twoje dane nie są dostępne natychmiast po wezwaniu do $.ajax ponieważ jest asynchroniczny. Obietnice to miła abstrakcja dla funkcji, która mówi: nie mogę zwrócić ci danych, ponieważ ich jeszcze nie mam i nie chcę blokować i zmuszać cię do czekania, więc oto obietnica zamiast tego, będziesz mógł z nich później korzystać, lub po prostu dać je komuś innemu i skończyć z tym.

Zobacz też DEMO.

Aktualizacja (2015)

Obecnie (stan na Marzec 2015) obietnice jQuery nie są zgodność ze specyfikacją Promises/a+ , co oznacza, że mogą one nie współpracować zbyt dobrze z innymi Promises/a+ zgodne implementacje .

Jednak jQuery obiecuje w nadchodzącej wersji 3.x będzie zgodne ze specyfikacją Promises/a+ (podziękowania dla Benjamina Gruenbauma za wskazanie tego). Obecnie (stan na Maj 2015) stabilne wersje jQuery to 1.x i 2.x.

To co wyjaśniłem powyżej (w marcu 2011) to sposób użycia jQuery Deferred Objects do zrobienia czegoś asynchronicznie, co w kodzie synchronicznym zostanie osiągnięte przez zwrócenie wartości.

Ale synchroniczne wywołanie funkcji może zrobić dwie rzeczy - może zwrócić wartość (jeśli może) lub rzucić wyjątek (jeśli nie może zwrócić wartości). Promises / A+ rozwiązuje oba te przypadki użycia w sposób, który jest tak samo potężny, jak obsługa wyjątków w kodzie synchronicznym. Wersja jQuery obsługuje odpowiednik zwracania wartości tylko dobrze, ale odpowiednik skomplikowanej obsługi wyjątków jest nieco problematyczny.

W szczególności, cały punkt obsługi wyjątków w kodzie synchronicznym to nie tylko rezygnacja z ładnej wiadomości, ale próba rozwiązania problemu i kontynuowania wykonywania, lub ewentualnie ponowne rozważenie tego samego lub innego wyjątku dla innych części programu do obsługi. W kodzie synchronicznym masz stos połączeń. W asynchronicznym wywołaniu nie masz i Zaawansowana obsługa wyjątków wewnątrz twojego obietnice wymagane przez specyfikację Promises / A+ mogą naprawdę pomóc w pisaniu kodu, który będzie obsługiwał błędy i wyjątki w znaczący sposób, nawet w złożonych przypadkach użycia.

[26]} różnice między jQuery i innych implementacji, i jak przekonwertować obietnice jQuery do obietnic / a + zgodne, zobacz pochodzących z jQuery przez Kris Kowal et al. na wiki Biblioteki Q i obietnice przybywają w JavaScript przez Jake Archibald na HTML5 Rocks.

Jak zwrócić prawdziwe obietnica

Funkcja z mojego przykładu powyżej:

function testAjax() {
  return $.ajax({
      url: "getvalue.php"
  });
}

Zwraca obiekt jqXHR, który jest jQuery Deferred Object .

Aby przywrócić prawdziwą obietnicę, możesz zmienić ją na - używając metody z Q wiki :

function testAjax() {
  return Q($.ajax({
      url: "getvalue.php"
  }));
}

Lub, używając metody z artykułu HTML5 Rocks :

function testAjax() {
  return Promise.resolve($.ajax({
      url: "getvalue.php"
  }));
}

To Promise.resolve($.ajax(...)) jest również to, co zostało wyjaśnione w dokumentacji promise modułu i powinno działać z ES6 Promise.resolve().

Aby korzystać z ES6 Promises dzisiaj możesz użyć es6-promise module ' S polyfill() Jake Archibald.

Aby zobaczyć, gdzie można użyć obietnic ES6 bez polyfill, zobacz: Czy mogę użyć: Promises .

Aby uzyskać więcej informacji zobacz:

Przyszłość jQuery

Przyszłe wersje jQuery (począwszy od 3.x-aktualne wersje stabilne z maja 2015 to 1.x i 2.x) będzie zgodny ze specyfikacją Promises/a+ (podziękowania dla Benjamina Gruenbauma za wskazanie tego w komentarzach). " dwie zmiany, na które już zdecydowaliśmy, to Zgodność Promise / A + dla naszej odroczonej implementacji [...]" (jQuery 3.0 i przyszłość Web development ). Aby uzyskać więcej informacji zobacz: jQuery 3.0: następne generacje autorstwa Dave ' a Methvina i jQuery 3.0: więcej interoperacyjności, mniej Internetu Explorer by Paul Krill.

Ciekawe rozmowy

  • W 2013 roku, po raz pierwszy w historii, pojawiła się nowa wersja gry, która ukazała się w 2014 roku.]}
  • odkupienie od Callback Hell Michaela Jacksona i Domenica Denicola (HTML5DevConf 2013)
  • to strona internetowa, w której znajdziesz wiele ciekawych informacji na temat języka JavaScript.]}

Aktualizacja (2016)

Jest nowa składnia w ECMA-262, wydanie 6, sekcja 14.2 o nazwie arrow funkcje , które mogą być użyte do dalszego uproszczenia powyższych przykładów.

[26]} używanie API jQuery zamiast:
promise.success(function (data) {
  alert(data);
});

Możesz napisać:

promise.success(data => alert(data));
Nie jest to jednak możliwe.]}
promise.then(data => alert(data));

Pamiętaj, aby zawsze używać obsługi odrzucania albo z:

promise.then(data => alert(data), error => alert(error));

Lub z:

promise.then(data => alert(data)).catch(error => alert(error));

Zobacz tę odpowiedź, aby zobaczyć, dlaczego zawsze powinieneś używać obsługi odrzuceń z obietnicami: {]}

Oczywiście w tym przykładzie możesz użyć tylko promise.then(alert), ponieważ po prostu wywołujesz alert z tymi samymi argumentami, co wywołanie zwrotne, ale składnia arrow jest bardziej ogólna i pozwala pisać rzeczy takie jak:

promise.then(data => alert("x is " + data.x));

Nie każda przeglądarka obsługuje jeszcze tę składnię, ale są pewne przypadki, w których masz pewność, na jakiej przeglądarce będzie działał Twój kod - np. pisząc rozszerzenie Chrome , dodatek Firefox lub aplikację komputerową używającą Elektron, NW.js lub AppJS (zobacz ta odpowiedź Po szczegóły).

Aby uzyskać obsługę funkcji strzałek, zobacz:

Aktualizacja (2017)

Istnieje jeszcze nowsza składnia o nazwie funkcje asynchroniczne z nowym await słowem kluczowym, które zamiast tego kodu:

functionReturningPromise()
    .then(data => console.log('Data:', data))
    .catch(error => console.log('Error:', error));

Pozwala napisz:

try {
    let data = await functionReturningPromise();
    console.log('Data:', data);
} catch (error) {
    console.log('Error:', error);
}

Można go używać tylko wewnątrz funkcji utworzonej za pomocą słowa kluczowego async. Aby uzyskać więcej informacji, zobacz:

[26]}Aby uzyskać wsparcie w przeglądarkach, zobacz:

Dla wsparcie w Node, zobacz:

W miejscach, gdzie nie masz natywnego wsparcia dla async i await możesz użyć Babel:

Lub z nieco inną składnią podejście oparte na generatorze jak w co lub Bluebird koroutines:

Więcej informacji

Kilka innych pytań o obietnice, aby uzyskać więcej szczegółów:

 361
Author: rsp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:25

Możesz dodać opcję asynchroniczną do false i return poza wywołaniem ajax.

function testAjax() {
    var result="";
    $.ajax({
      url:"getvalue.php",
      async: false,  
      success:function(data) {
         result = data; 
      }
   });
   return result;
}
 161
Author: Ging3r,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-10 07:40:03

Idk jeśli to rozwiązaliście, ale polecam inny sposób na zrobienie tego i działa:)

    ServiceUtil = ig.Class.extend({
        base_url : 'someurl',

        sendRequest: function(request)
        {
            var url = this.base_url + request;
            var requestVar = new XMLHttpRequest();
            dataGet = false;

            $.ajax({
                url: url,
                async: false,
                type: "get",
                success: function(data){
                    ServiceUtil.objDataReturned = data;
                }
            });
            return ServiceUtil.objDataReturned;                
        }
    })

Więc główną ideą jest to, że dodając async: false, wszystko czeka aż dane zostaną pobrane. Następnie przypisujesz go do zmiennej statycznej klasy i wszystko działa magicznie :)

 -1
Author: user1509803,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-01 08:30:33

Zobacz przykład jquery docs: http://api.jquery.com/jQuery.ajax / (około 2/3 strony)

Możesz szukać następującego kodu:

    $.ajax({
     url: 'ajax/test.html',
     success: function(data) {
     $('.result').html(data);
     alert('Load was performed.');
   }
});

Ta sama strona...niżej.

 -11
Author: Techism,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-22 10:11:40