Praktyczny przykład użycia deferred objects jQuery 1.5

Wyobraź sobie prostą aplikację, która regularanie (ajaxem) ściąga nowe dane z serwera. Bardzo prosty przykład:
szablon html (intex.html):

<html>
	<head>
		<style>
			#message{
				background: #dd2222;
				opacity: 0;
			}
			#data{
				border: 1px solid grey;
				width: 300px;
				min-height: 200px;
			}
		</style>
		<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
	</head>
	<body>
		<div id="message"></div>
		<ul id="data"></div>
		<script>
// tutaj Javascript*!
		</script>
	</body>
</html>

*kod javascript, tak mógłby wyglądać gdybyśmy go pisali w jQuery<1.5:

(function() {
   var _msg = $(“#message”), 
      _data = $(“#data”),
      _callee = arguments.callee;
   $.getJSON(“data.php”, function(data, texrStatus, jqXHR){
      _msg.html(data.message).css({opacity: 1}).
         animate({opacity: 0}, 5000, “swing”);
      $.each(data.data, function(key, val){
         $( “
  • “, { html: val }).appendTo(_data); }); window.setTimeout(function(){_callee();}, 10000); }); })()
  • A oto skrypt data.php, która zwraca JSON:

    {"message":"new stuff!","data":["<?php echo time()?>","<?php echo date("Y-m-d H:i:s")?>"]}
    

    W miarę rozwoju całego systemu takie funkcje callback obsługujące zapytania rozrastają się i puchną. Od wersji 1.5 jQuery przynosi ze sobą tzw. defferred objects. Wszystkie metody “ajaxowe” zwracają teraz obiekt, który jest “obietnicą” wykonania XHR’a. Oznacza to, że możemy pracować na tym obiekcie i nieco rozluźnić powiązanie poszczególnych “zadań” do wykonania po udanym zapytaniu.

    Możemy nasz skrypt obsługujący XHTTPRequest, przepisać w następujący sposób:

    (function() {
    	var _msg = $("#message"), 
    		_data = $("#data"),
    		_callee = arguments.callee, 
    		_jsonCall = $.getJSON("data.php", function(){
    			window.setTimeout(function(){_callee();}, 10000)
    		});
    
    	_jsonCall.done(function(data){
    		_msg.html(data.message).css({opacity: 1}).
    			animate({opacity: 0}, 5000, "swing");		
    	});
    	_jsonCall.done(function(data){
    		$.each(data.data, function(key, val){
    			$("<li>", {
    				html: val
    			}).appendTo(_data);
    		});
    	});
    })()
    

    Jak widać stary sposób nadal działa (linia 5) – domyślnie zapytanie ma za zadanie się wykonać i wywołać się ponownie za 10 sekund. To co dalej dzieje się z danymi może się zmieniać, więc wyciągnąłem te fragmenty na zewnątrz. W linii 9 pod zdarzenie success podpinam wyświetlenie alertu i wywołanie wszystkich związanych z nim bajerów.
    W linii 13 z kolei do tego samego zdarzenia podpinam fragment odpowiadający za wyświetlenie szczegółów na stronie.

    Mogę to wszystko zrobić dlatego, że przekazanie funkcji do metody success działa dwojako, w zależności od stanu obiektu Deffered

    1. Jeśli zapytanie zakończyło się już sukcesem – funkcja jest po prostu odpalana
    2. W przeciwnym wypadku – jest zakolejkowana do zdarzenia ‘success’ tego obiektu

    Oczywiście to nie koniec możliwości Deferred – nie wspomniałem nawet o tym, że można jako parametr przekazać tablicę funkcji.

    Jeśli spodobał Ci się ten artykuł i chciałbyś, żebym napisał więcej przykładów z użyciem deferred objects, to napisz mi proszę o tym w komentarzu.

    Share Button

    6 thoughts on “Praktyczny przykład użycia deferred objects jQuery 1.5

    1. Pingback: Przykład użycia deffered objects - nowego ficzeru jQuery 1.5 - develway.pl

    2. dzięki, taki feedback też jak najbardziej mile widziany :)

    3. Znalazłem dziś tego bloga – miło wiedzieć że ktoś w taki przystępny sposób pisze o zakamarkach JS. Czekam na więcej ciekawostek, w tym dotyczących nowości JQuery (co rusz pojawiają się w kolejnych wersjach użyteczne metody, o których miło by było poczytać po polsku). Blog ląduje w RSS :)

    4. Po co te całe deffered objects, skoro od wersji 1.0 można używać po prostu:
      $.ajax({url: ‘…’, success: mojaFunkcjaGdySukces, error: mojaFunkcjaGdyBlad});

    Leave a Reply

    Your email address will not be published. Required fields are marked *