Bluebird NPM: Obietnica Bluebird JS z przykładem
⚡ Inteligentne podsumowanie
Bluebird JS to w pełni funkcjonalna biblioteka Promise dla JavaSkrypt, którego definiującą zdolnością jest obietnicowanie: konwertowanie modułów Node opartych na wywołaniach zwrotnych na moduły zwracające obietnice, dzięki czemu cała biblioteka, taka jak MongoDB Sterownik może być używany asynchronicznie.

Co to jest Bluebird JS?
Bluebird JS to w pełni funkcjonalna biblioteka Promise dla JavaSkrypt. Jego najmocniejszą stroną jest możliwość „obiecania” (promisify) innych modułów Node, aby móc z nich korzystać asynchronicznie. Promisify to koncepcja stosowana do funkcji wywołania zwrotnego, która gwarantuje, że każda wywołana funkcja zwraca wartość.
Więc jeśli node.js moduł zawiera funkcję wywołania zwrotnego, która nie zwraca wartości, obiecując, że moduł automatycznie modyfikuje wszystkie funkcje w nim zawarte, tak aby każda z nich zwracała wartość.
Oznacza to, że możesz użyć Bluebird do wykonania MongoDB moduł jest uruchamiany asynchronicznie, co znacznie ułatwia pisanie aplikacji Node.js.
Poniższy przykład najpierw nawiązuje połączenie z kolekcją „Employee” w bazie danych „EmployeeDB”. Po nawiązaniu połączenia pobierane są wszystkie rekordy z kolekcji i wyświetlane w konsoli.
Jak generować obietnice za pomocą biblioteki Bluebird JS
Oto przykład krok po kroku pokazujący, jak generować obietnice za pomocą biblioteki Bluebird JS.
Krok 1) Instalowanie modułów NPM
Aby korzystać z Bluebirda w aplikacji Node, wymagany jest moduł Bluebird. Zainstaluj go za pomocą poniższego polecenia:
npm install bluebird
Krok 2) Dodaj moduł Bluebird
Następnym krokiem jest uwzględnienie modułu Bluebird w kodzie i złożenie obietnicy całości MongoDB moduł. Obiecujące jest tutaj to, że Bluebird zapewnia, że każda metoda zdefiniowana w MongoDB biblioteka spełnia obietnicę.
Code Wyjaśnienie:
-
requirePolecenie zawiera bibliotekę Bluebird. - Bluebird's
.promisifyAll()metoda tworzy asynchroniczną wersję każdej metody MongoDB moduł udostępnia, więc każdy z nich działa w tle i zwraca obietnicę.
Krok 3) Połącz się z bazą danych
Ostatnim krokiem jest połączenie się z bazą danych, pobranie wszystkich rekordów ze zbioru i wyświetlenie ich w dzienniku konsoli.
Code Wyjaśnienie:
- Wskazówka
connectAsyncmetoda jest stosowana zamiast normalnejconnectmetoda. Bluebird dodaje Asynchronizacja przyrostek do każdej metody w MongoDB biblioteka, która rozróżnia wywołania zwracające obietnice od tych, które ich nie zwracają. Metody bez sufiksu Async nie dają takiej gwarancji. - Podobny do
connectAsyncThefindAsyncMetoda zwraca wszystkie rekordy w MongoDB Kolekcja „Pracownik”. - If
findAsynczostanie rozwiązany pomyślnie, następujący blok przejdzie przez każdy rekord w kolekcji i wyświetli go w dzienniku konsoli.
Jeśli powyższe kroki zostaną wykonane prawidłowo, wszystkie dokumenty w kolekcji Pracownicy zostaną wyświetlone w konsoli, jak pokazano na poniższym wyjściu.
Oto kompletny kod, w celach informacyjnych:
var Promise = require('bluebird'); // promisifyAll adds an Async variant of every MongoDB method var mongoClient = Promise.promisifyAll(require('mongodb')).MongoClient; mongoClient.connectAsync('mongodb://localhost/EmployeeDB') .then(function(db) { return db.collection('Employee').findAsync({}); }) .then(function(cursor) { cursor.each(function(err, doc) { console.log(doc); }); });
⚠️ Uwaga dotycząca wersji sterownika: powyższy kod ma na celu MongoDB Sterownik węzła 2.x, gdzie connect rozwiązuje się za pomocą obiektu bazy danych. Ze sterownika 3.0 i nowsze rozwiązuje się za pomocą MongoClient, więc łańcuch musi wywołać client.db('EmployeeDB').collection('Employee') zamiast db.collection('Employee')Nowoczesne wersje sterowników również zwracają już natywne obietnice, co sprawia, że promisifyAll niepotrzebne dla MongoDB konkretnie.
Bluebird kontra Native Promises: Którego użyć
Kiedy Bluebird został po raz pierwszy napisany, Node w ogóle nie obsługiwał obietnic, więc biblioteka wypełniła istotną lukę w platformie. Node dostarczał natywne obietnice od wersji 4 i async/await od wersji 7.6, co znacząco zmienia sposób obliczeń dla każdego, kto rozpoczyna dziś projekt.
| WYGLĄD | Bluebird | Rodzime obietnice |
|---|---|---|
| Zależność | Pakiet npm do zainstalowania i utrzymania | Wbudowane w środowisko wykonawcze |
| Obiecujące wywołania zwrotne | promisifyAll() konwertuje cały moduł |
util.promisify() konwertuje jedną funkcję |
| Dodatkowi pomocnicy | mapa, filtr, rekwizyty, każdy, limit czasu, anulowanie | wszystkie, wszystkieOsiedlone, dowolne, tylko rasa |
| Długi stos traces | Tak, gdy włączone | Ulepszone, ale krótsze |
| Najlepszy dla | Biblioteki wywołań zwrotnych starszej generacji, pomocnicy współbieżności | Nowy kod i wszystko, co używa async wait |
Wybierz natywne obietnice dla nowych zadań, ponieważ nie wymagają one zależności i integrują się bezpośrednio z async wait. Sięgnij po Bluebird, gdy zależność nadal udostępnia jedynie wywołania zwrotne lub gdy jej funkcje pomocnicze współbieżności, takie jak… Promise.map dzięki limitowi współbieżności można zaoszczędzić znaczną ilość kodu.
Jak radzić sobie z błędami za pomocą obietnic Bluebird
Powyższy przykład nie ma ścieżki błędu. Jeśli MongoDB nie działa lub nazwa kolekcji jest błędna, łańcuch obietnic zostaje odrzucony i nic nie jest drukowane — proces po prostu kończy działanie bez wyjaśnienia. Każdy łańcuch obietnic potrzebuje obsługi terminala.
Bluebird wspiera .catch() do odrzuceń i .finally() do czyszczenia, które musi działać w obu kierunkach. Obsługuje również bloki typu catch, które obsługują jedną klasę błędów, jednocześnie pozwalając innym na propagację.
var Promise = require('bluebird'); var mongoClient = Promise.promisifyAll(require('mongodb')).MongoClient; var connection; mongoClient.connectAsync('mongodb://localhost/EmployeeDB') .then(function(db) { connection = db; return db.collection('Employee').findAsync({}); }) .then(function(cursor) { return cursor.toArrayAsync(); }) .then(function(docs) { docs.forEach(function(doc) { console.log(doc); }); }) .catch(Promise.TimeoutError, function(err) { console.error('The database did not respond in time.'); }) .catch(function(err) { // Any other rejection from any step above arrives here console.error('Query failed:', err.message); }) .finally(function() { // Runs on success and on failure, so the socket always closes if (connection) { connection.close(); } });
Tutaj liczą się trzy nawyki. Po pierwsze, umieść .catch() na końcu, a nie po każdym kroku, ponieważ jeden program obsługi terminala odbiera odrzucenia z każdego poprzedniego ogniwa w łańcuchu. Po drugie, użyj .finally() do zwalniania zasobów, takich jak połączenie z bazą danych, ponieważ działa ono zarówno na ścieżkach sukcesu, jak i porażki. Po trzecie, nigdy nie pozostawiaj łańcucha bez haczyka: nieobsłużone odrzucenie kończy proces węzła w bieżących wersjach, a Bluebird wyświetli o tym wyraźne ostrzeżenie. Włączanie długiego stosu traces podczas rozwoju z Promise.config({ longStackTraces: true }) znacznie ułatwia ustalenie przyczyny odrzucenia.
Typowe błędy Bluebird Promisify i ich rozwiązania
Większość problemów z Bluebird wynika z konwencji nazewnictwa Promised (promisified) lub z mieszania stylów wywołania callback i promise w tym samym łańcuchu, a nie z błędu samej biblioteki. Każdy z poniższych symptomów opisuje przyczynę i sposób rozwiązania.
- „connectAsync nie jest funkcją”: moduł był wymagany bezpośrednio, a nie przez
promisifyAll(), więc nie istnieją żadne warianty asynchroniczne. Zawiń wywołanie require, jak pokazano powyżej. - Wywołanie metody plain i otrzymanie wartości undefined:
connect()Nadal oczekuje wywołania zwrotnego. Tylko kopia z sufiksem Async zwraca obietnicę. - Przekazywanie wywołania zwrotnego do metody asynchronicznej: nie dostarczaj ani wywołania zwrotnego, ani
awaita obietnica zostaje spełniona w sposób niezauważalny. Używaj jednego stylu na wywołanie, a nie obu. - promisifyAll na bibliotece już opartej na obietnicach: Nieszkodliwe, ale bezcelowe i powoduje mylące podwójne sufiksy w nazwach. Najpierw sprawdź dokumentację biblioteki.
- Ciche gubienie błędów: łańcuch bez
.catch()Ukrywa przyczynę odrzucenia, dopóki Node nie zgłosi nieobsłużonego odrzucenia i nie zakończy działania. Zawsze kończ łańcuch za pomocą catch, nawet w krótkich skryptach.



