Czy po dodaniu natywnej obsługi obietnic przez Node.js nadal istnieją powody do korzystania z bibliotek takich jak Q lub BlueBird?
Na przykład, jeśli zaczynasz nowy projekt i załóżmy, że w tym projekcie nie ma żadnych zależności korzystających z tych bibliotek, czy możemy powiedzieć, że tak naprawdę nie ma już powodów, aby używać takich bibliotek?
Odpowiedzi:
Stare powiedzenie głosi, że należy wybrać odpowiednie narzędzie do pracy. Obietnice ES6 zapewniają podstawy. Jeśli wszystko, czego kiedykolwiek pragniesz lub potrzebujesz, to podstawy, to powinno / powinno działać dobrze dla Ciebie. Ale w koszu na narzędzia jest więcej narzędzi niż tylko podstawy i są sytuacje, w których te dodatkowe narzędzia są bardzo przydatne. I twierdzę, że w obietnicach ES6 brakuje nawet niektórych podstawowych elementów, takich jak obietnica, które są przydatne w prawie każdym projekcie node.js.
Najbardziej znam bibliotekę obietnic Bluebird więc będę rozmawiać głównie z mojego doświadczenia z tą biblioteką.
Oto moje 6 głównych powodów, dla których warto skorzystać z bardziej wydajnej biblioteki Promise
Niesamowite interfejsy asynchroniczne -
.promisify()
i.promisifyAll()
są niezwykle przydatne do obsługi wszystkich tych interfejsów asynchronicznych, które wciąż wymagają zwykłych wywołań zwrotnych i jeszcze nie zwracają obietnic - jeden wiersz kodu tworzy obiecaną wersję całego interfejsu.Szybszy - Bluebird jest znacznie szybszy niż natywne obietnice w większości środowisk.
Sekwencjonowanie iteracji tablicy asynchronicznej -
Promise.mapSeries()
lubPromise.reduce()
pozwala na iterację przez tablicę, wywołując operację asynchroniczną na każdym elemencie, ale sekwencjonując operacje asynchroniczne, aby następowały kolejno po sobie, a nie wszystkie jednocześnie. Możesz to zrobić albo dlatego, że wymaga tego serwer docelowy, albo dlatego, że musisz przekazać jeden wynik do drugiego.Wielokrotne wypełnianie - jeśli chcesz używać obietnic w starszych wersjach klientów przeglądarki, i tak będziesz potrzebował wielokrotnego wypełniania. Może również uzyskać sprawny wypełniacz. Ponieważ node.js ma obietnice ES6, nie potrzebujesz wielokrotnego wypełniania w node.js, ale możesz to zrobić w przeglądarce. Jeśli kodujesz zarówno serwer, jak i klient node.js, bardzo przydatne może być posiadanie tej samej biblioteki obietnic i funkcji w obu (łatwiejsze udostępnianie kodu, przełączanie kontekstu między środowiskami, stosowanie typowych technik kodowania dla kodu asynchronicznego itp. .).
Inne użyteczne funkcje - Bluebird ma
Promise.map()
,Promise.some()
,Promise.any()
,Promise.filter()
,Promise.each()
iPromise.props()
z których wszystkie są czasami przydać. Chociaż operacje te można wykonywać z obietnicami ES6 i dodatkowym kodem, Bluebird jest wyposażony w te operacje, które są już wstępnie zbudowane i przetestowane, więc korzystanie z nich jest prostsze i mniej kodowane.Wbudowane ostrzeżenia i ślady pełnego stosu - Bluebird ma wiele wbudowanych ostrzeżeń, które ostrzegają o problemach, które prawdopodobnie są błędnym kodem lub błędem. Na przykład, jeśli wywołasz funkcję, która tworzy nową obietnicę w
.then()
module obsługi bez zwracania tej obietnicy (w celu powiązania jej z bieżącym łańcuchem obietnic), to w większości przypadków jest to przypadkowy błąd, a Bluebird da ci ostrzeżenie efekt. Inne wbudowane ostrzeżenia Bluebird są opisane tutaj .Oto więcej szczegółów na te różne tematy:
PromisifyAll
W każdym projekcie node.js natychmiast używam Bluebird wszędzie, ponieważ
.promisifyAll()
dużo używam na standardowych modułach node.js, takich jakfs
moduł.Node.js sam w sobie nie zapewnia obiecującego interfejsu dla wbudowanych modułów, które wykonują asynchroniczne operacje we / wy jak
fs
moduł. Tak więc, jeśli chcesz używać obietnic z tymi interfejsami, możesz albo ręcznie kodować opakowanie obietnicy wokół każdej funkcji modułu, której używasz, albo uzyskać bibliotekę, która może to zrobić dla ciebie, lub nie używać obietnic.Bluebird
Promise.promisify()
iPromise.promisifyAll()
zapewniają automatyczne zawijanie asynchronicznych interfejsów API wywołujących node.js w celu zwrócenia obietnic. Jest to niezwykle przydatne i oszczędza czas. Używam tego cały czas.Oto przykład, jak to działa:
Alternatywą byłoby ręczne utworzenie własnego opakowania obietnicy dla każdego
fs
interfejsu API, którego chcesz użyć:I musisz to zrobić ręcznie dla każdej funkcji API, której chcesz użyć. To oczywiście nie ma sensu. To jest kod płyty. Równie dobrze możesz uzyskać narzędzie, które wykona to za Ciebie. Bluebird's
Promise.promisify()
iPromise.promisifyAll()
są takim narzędziem.Inne przydatne funkcje
Oto niektóre z funkcji Bluebird, które szczególnie uważam za przydatne (poniżej znajduje się kilka przykładów kodu, w jaki sposób można zapisać kod lub przyspieszyć rozwój):
Oprócz swojej przydatnej funkcji
Promise.map()
obsługuje również opcję współbieżności, która pozwala określić, ile operacji powinno być uruchomionych w tym samym czasie, co jest szczególnie przydatne, gdy masz dużo do zrobienia, ale nie może przytłoczyć niektórych z zewnątrz ratunek.Niektóre z nich można zarówno nazwać samodzielnymi, jak i użyć w obietnicy, która sama przekształca się w iterowalną, która może zaoszczędzić dużo kodu.
Polyfill
W projekcie przeglądarki, ponieważ generalnie chcesz nadal obsługiwać niektóre przeglądarki, które nie obsługują technologii Promise, i tak będziesz potrzebować wielokrotnego wypełniania. Jeśli używasz również jQuery, czasami możesz po prostu skorzystać z obsługi obietnic wbudowanej w jQuery (chociaż jest to boleśnie niestandardowe pod pewnymi względami, być może naprawione w jQuery 3.0), ale jeśli projekt wymaga jakiejkolwiek znaczącej aktywności asynchronicznej, znajduję rozszerzone funkcje Bluebird są bardzo przydatne.
Szybciej
Warto również zauważyć, że obietnice Bluebird wydają się znacznie szybsze niż obietnice wbudowane w V8. Zobacz ten post, aby uzyskać więcej dyskusji na ten temat.
Big Thing Node.js brakuje
To, co skłoniłoby mnie do rozważenia używania Bluebird mniej w rozwoju node.js, to gdyby node.js został wbudowany w funkcję promisify, abyś mógł zrobić coś takiego:
Lub po prostu zaoferuj już obiecane metody jako część wbudowanych modułów.
Do tego czasu robię to z Bluebird:
Wydaje się nieco dziwne, że obsługa obietnic ES6 jest wbudowana w node.js i żaden z wbudowanych modułów nie zwraca obietnic. To musi zostać uporządkowane w node.js. Do tego czasu używam Bluebird do promowania całych bibliotek. Wygląda więc na to, że obietnice są teraz implementowane w node.js w około 20%, ponieważ żaden z wbudowanych modułów nie pozwala na użycie obietnic bez ich ręcznego zawijania.
Przykłady
Oto przykład prostych obietnic vs. obietnicy Bluebird i
Promise.map()
do równoległego czytania zestawu plików i powiadamiania o zakończeniu wszystkich danych:Proste obietnice
Bluebird
Promise.map()
iPromise.promisifyAll()
Oto przykład zwykłych obietnic vs. obietnic Bluebird i
Promise.map()
podczas odczytywania wiązki adresów URL ze zdalnego hosta, na którym możesz odczytać maksymalnie 4 naraz, ale chcesz zachować tyle żądań równolegle, ile jest to dozwolone:Zwykłe obietnice JS
Bluebird obiecuje
źródło
return new Promise(function(resolve, rejct)
. Powinno być:reject
util.promisify
teraz, choć nie ma bezpośredniegopromisifyAll
odpowiednika.fs
, ale wciąż istnieją inne powody, aby używać Bluebird (moim szczególnym faworytem jestconcurrency
opcjaPromise.map()
), aby nie przytłoczyć usługi docelowej, do której musisz wysłać kilka równoległych żądań. Ponadto wciąż wiele innych nie obiecanych interfejsów do korzystania z promisifyAll z Bluebird. Powoli jednak powody, dla których od razu chwytamy Bluebirda w każdym nowym projekcie, zanikają, ponieważ sam node.js rozwija swoją wbudowaną obsługę obietnic.