2013-01-02 17 views
50

Powiel możliwe:
What are the differences between Deferred, Promise and Future in Javascript?Asynchronous JavaScript - oddzwaniania vs Odroczony/Obietnica

Ostatnio byłem wszelkich starań, aby poprawić jakość moich aplikacji JavaScript.

Jednym z przyjętych przeze mnie wzorców jest użycie osobnego obiektu "kontekst danych" w celu załadowania danych do mojej aplikacji (wcześniej robiłem to bezpośrednio w moich modelach widoku).

Poniższy przykład zwraca dane, który jest zainicjowany na kliencie:

var mockData = (function($, undefined) { 

    var fruit = [ 
     "apple", 
     "orange", 
     "banana", 
     "pear" 
     ]; 

    var getFruit = function() { 
     return fruit; 
    }; 

    return { 
     getFruit: getFruit 
    } 
})(jQuery); 

W większości przypadków będziemy ładowanie danych z serwera, więc nie możemy powrócić natychmiastową reakcję. Wydaje się, mam dwie opcje, jak sobie z tym poradzić w naszym API:

  1. używając zwrotnego
  2. Zwracanie promise.

Wcześniej bym zawsze stosować metodę callback:

var getFruit = function(onFruitReady) { 
    onFruitReady(fruit); 
}; 

// ... 

var FruitModel = function(dataContext, $) { 
    return { 
     render: function() { 
      dataContext.getFruit(function(fruit) { 
       // do something with fruit 
      }); 
     } 
    }; 
}; 

Jednak widzę, jak to możliwe, aby skończyć w piekle zwrotnego, zwłaszcza przy tworzeniu złożonych aplikacji JavaScript.

Potem natknąłem się na wzór projektu Obietnice. Zamiast wymogu rozmówcę do zasilania zwrotnego, ja zamiast zwracać „obietnice”, które mogą być obserwowane:

var getFruit = function() { 
    return $.Deferred().resolve(fruit).promise(); 
}; 

// ... 
dataContext.getFruit().then(function(fruit) { 
    // do something with fruit 
}); 

widzę oczywiste korzyści wynikające z zastosowania tego wzoru, zwłaszcza, że ​​mogę wait z wielu obiektów, które mogłyby odroczonego może być bardzo przydatny podczas ładowania danych inicjalizacyjnych dla pojedynczej aplikacji strony.

Jednakże, bardzo chciałbym zrozumieć zalety i wady każdego wzoru, zanim zacznę używać go w gniewie. Interesuje mnie również, czy jest to kierunek, w którym zmierzają inne biblioteki. Wydaje się, że tak jest w przypadku jQuery.

Oto link na skrzypce, którego używam do testowania.

+4

No dobra wiadomość: API Ajax jQuery * już * Obietnice zamian! – Pointy

+0

[Zapoznaj się z mechanizmem tutaj.] (Http://api.jquery.com/jQuery.ajax/#jqXHR) – Pointy

+0

Tak, właśnie w ten sposób natknąłem się na wzór, ponieważ szukałem sposobu abstrakcyjne wywołania ajaxowe. –

Odpowiedz

18

Obietnice zależą również od wywołań zwrotnych za sceną, więc nie jest to jedna z nich.

Zaletą wywołania zwrotnego jest to, że można je łatwo wdrożyć za pomocą zwykłego kodu JavaScript (na przykład w wywołaniach ajax).

Obietnice wymagają dodatkowej warstwy abstrakcji, co zwykle oznacza, że ​​będziesz polegać na bibliotece (nie jest to problemem w twoim przypadku, ponieważ już używasz jQuery). Są doskonałe, gdy równolegle obsługuje się wiele połączeń asynchronicznych.

+9

Uwaga: od marca 2014 r. Przeglądarki zaczęły wdrażać lokalne obietnice , więc moje oświadczenie odnosi się tylko do polyfills. – Christophe

3

z lektury jQuery docs że @Pointy związane, to brzmi jak różnica jest taka, że ​​odroczony API pozwala określić więcej niż jedną funkcję do wywołania kiedy Twój wniosek uzupełnia:

Jak jQuery 1.5 , błąd (niepowodzenie), sukces (zrobione) i kompletny (zawsze, jak w jQuery 1.6) haki wywołania zwrotnego są kolejkami zarządzanymi first-in, first-out. Oznacza to, że możesz przypisać więcej niż jedno wywołanie zwrotne dla każdego haka. Zobacz Metody odroczonego obiektu, które są wewnętrznie zaimplementowane dla tych haków wywołania zwrotnego $ .ajax().

Zobacz także: deferred.then()

+1

Nie chodzi o to, że Odroczone/obietnice * pozwalają * ty określić więcej niż jedną funkcję, która ma być wywołana, o ile robią to * łatwiej *. Szczególnymi cechami są to, że (a) można dodać funkcje (np. '.done()' lub '.fail()') w dowolnym miejscu kodu, pod warunkiem, że Odroczony/obietnica jest w zasięgu i (b) funkcje dodany po odroczeniu został rozwiązany/odrzucony natychmiast się zwolni. Poprzez ujawnienie swojego wewnętrznego narzędzia '.Callbacks()', jQuery sprawia, że ​​tego rodzaju funkcjonalność * jest możliwa * bez użycia Deferreds/promises, ale odciąża kodowanie/debugowanie. –

Powiązane problemy