2012-09-14 11 views
11

Jestem całkowicie nowy w świecie Javascript/jquery i potrzebuję pomocy. W tej chwili piszę jedną stronę HTML, gdzie muszę wykonać 5 różnych wywołań Ajax, aby uzyskać dane do wykreślania wykresów. Teraz wzywam tych 5 połączeń ajax jak to:Równoległe wywołania Ajax w JavaScript/jQuery

$(document).ready(function() { 
    area0Obj = $.parseJSON($.ajax({ 
     url : url0, 
     async : false, 
     dataType : 'json' 
    }).responseText); 

    area1Obj = $.parseJSON($.ajax({ 
     url : url1, 
     async : false, 
     dataType : 'json' 
    }).responseText); 
. 
. 
. 
    area4Obj = $.parseJSON($.ajax({ 
     url : url4, 
     async : false, 
     dataType : 'json' 
    }).responseText); 

    // some code for generating graphs 

)} // closing the document ready function 

Moim problemem jest to, że w powyższym scenariuszu, wszystkie wywołania Ajax będą seryjnie. Oznacza to, że po 1 zakończeniu połączenia 2 rozpoczyna się, gdy 2 kończy 3 itd. Każde wywołanie Ajax zajmuje około 5 - 6 sekund, aby uzyskać dane, co powoduje załadowanie całej strony na około 30 sekund. .

Próbowałem uczynić typ async jako prawdziwy, ale w takim przypadku nie otrzymuję danych od razu, aby wykreślić wykres, który pokonuje mój cel.

Moje pytanie brzmi: W jaki sposób mogę wykonać te połączenia równolegle, aby zacząć otrzymywać równolegle wszystkie te dane, a moja strona mogła zostać załadowana w krótszym czasie?

Z góry dziękuję.

+0

kto kazał ci uzyskać taką odpowiedź? –

Odpowiedz

22

Korzystanie jQuery.when (deferreds):

$.when($.ajax("/req1"), $.ajax("/req2"), $.ajax("/req3")).then(function(resp1, resp2, resp3){ 
    // plot graph using data from resp1, resp2 & resp3 
}); 

funkcja zwrotna wywoływana, gdy tylko wszystkie połączenia 3 Ajax są zakończone.

+0

Dzięki za to. To zadziałało dla mnie! – Raghuveer

+5

Warto tutaj zauważyć, że każda odpowiedź (resp1, resp2, resp3) będzie miała następującą strukturę: [data, statusText, jqXHR]. Musisz więc zadzwonić, np. Resp1 [0], aby uzyskać rzeczywiste dane z pierwszej odpowiedzi. –

0

W jQuery.ajax należy podać metodę wywołania zwrotnego, jak poniżej:

j.ajax({ 
     url : url0, 
     async : true, 
     dataType : 'json', 
     success:function(data){ 
      console.log(data); 
     } 
    } 

lub można korzystać bezpośrednio

jQuery.getJSON(url0, function(data){ 
    console.log(data); 
}); 

reference

2

Nie można tego zrobić za pomocą async: false - kod jest wykonywany synchronicznie, jak już wiesz (tzn. operacja nie rozpocznie się, dopóki nie zakończy się poprzednia).
Będziesz chciał ustawić async: true (lub po prostu go pominąć - domyślnie jest to prawda). Następnie zdefiniuj funkcję wywołania zwrotnego dla każdego wywołania AJAX. Wewnątrz każdego wywołania zwrotnego dodaj odebrane dane do tablicy. Następnie sprawdź, czy wszystkie dane zostały załadowane (arrayOfJsonObjects.length == 5). Jeśli tak, wywołaj funkcję, aby zrobić, co chcesz z danymi.

0

Nie będziesz w stanie poradzić sobie z tym jak twój przykład. Ustawienie asynchronizacji używa innego wątku, aby włączyć żądanie i pozwala kontynuować twoją aplikację.

W tym przypadku należy użyć nowej funkcji, która wykreśli obszar, a następnie użyć funkcji wywołania zwrotnego żądania ajax, aby przekazać dane do tej funkcji.

Na przykład:

$(document).ready(function() { 
    function plotArea(data, status, jqXHR) { 
     // access the graph object and apply the data. 
     var area_data = $.parseJSON(data); 
    } 

    $.ajax({ 
     url : url0, 
     async : false, 
     dataType : 'json', 
     success: poltArea 
    }); 

    $.ajax({ 
     url : url1, 
     async : false, 
     dataType : 'json', 
     success: poltArea 
    }); 

    $.ajax({ 
     url : url4, 
     async : false, 
     dataType : 'json', 
     success: poltArea 
    }); 

    // some code for generating graphs 

}); // closing the document ready function 
0

Wygląda na to trzeba wysłania żądania asynchronicznie i określenie funkcji zwrotnej, aby uzyskać odpowiedź.

W ten sposób poczekasz, aż zmienna zostanie pomyślnie przypisana (co oznacza, że ​​odpowiedź właśnie dotarła), dopóki nie przekaże następnego żądania. Po prostu użyj czegoś takiego.

$.ajax({ 
    url: url, 
    dataType: 'json', 
    data: data, 
    success: function(data) { 
    area0Obj = data; 
    } 
}); 

To powinno wystarczyć.

1

Spróbujmy zrobić to w ten sposób:

<script type="text/javascript" charset="utf-8"> 
    $(document).ready(function() { 
     var area0Obj = {responseText:''}; 
     var area1Obj = {responseText:''}; 
     var area2Obj = {responseText:''}; 

     var url0 = 'http://someurl/url0/'; 
     var url1 = 'http://someurl/url1/'; 
     var url2 = 'http://someurl/url2/'; 

     var getData = function(someURL, place) { 
      $.ajax({ 
       type  : 'POST', 
       dataType : 'json', 
       url  : someURL, 
       success : function(data) { 
        place.responseText = data; 
        console.log(place); 
       } 
      }); 
     } 

     getData(url0, area0Obj); 
     getData(url1, area1Obj); 
     getData(url2, area2Obj); 

    }); 
</script> 

jeśli po stronie serwera będzie smth.tak:

public function url0() { 
    $answer = array(
     array('smth' => 1, 'ope' => 'one'), 
     array('smth' => 8, 'ope' => 'two'), 
     array('smth' => 5, 'ope' => 'three') 
    ); 
    die(json_encode($answer)); 
} 

public function url1() { 
    $answer = array('one','two','three'); 
    die(json_encode($answer)); 
} 

public function url2() { 
    $answer = 'one ,two, three'; 
    die(json_encode($answer)); 
} 

Tak więc, jak widać, stworzył jedną funkcję getData() do pobierania danych z serwera i niż to nazywa się 3 razy. Wyniki będą odbierane w sposób asynchroniczny, na przykład pierwszy może uzyskać odpowiedź na trzecie połączenie i ostatni na pierwsze połączenie.

Konsola odpowiedź będzie:

[{"smth":1,"ope":"one"},{"smth":8,"ope":"two"},{"smth":5,"ope":"three"}] 

["one","two","three"] 

"one ,two, three" 

PS. przeczytaj: http://api.jquery.com/jQuery.ajax/ tam możesz wyraźnie zobaczyć informacje o async. Istnieje domyślna wartość parametru async = true.

Domyślnie wszystkie żądania są wysyłane asynchronicznie (to jest domyślnie ustawione na wartość true). Jeśli potrzebujesz synchronicznych żądań, ustaw tę opcję na false. Żądania między domenami i dataType: żądania "jsonp" nie obsługują operacji synchronicznych. Zauważ, że synchroniczne żądania mogą tymczasowo zablokować przeglądarkę, wyłączając wszelkie akcje, gdy żądanie jest aktywne ...

0

możesz połączyć wszystkie funkcje różnych funkcji ajax w jedną funkcję ajax, lub od 1 funkcji ajaxowej, zadzwoń do drugiej funkcje (w tym przypadku byłyby to strona prywatna/kontroler), a następnie zwracają wynik. Połączenia Ajax trochę utknęły, więc minimalizacja ich jest drogą do zrobienia.

możesz również sprawić, by funkcje ajaxowe były asynchroniczne (które zachowywałyby się jak normalne funkcje), a następnie renderować wykres na końcu, po tym jak wszystkie funkcje zwróciłyby swoje dane.

Powiązane problemy