Bluebird NPM: Lời hứa của Bluebird JS kèm ví dụ
⚡ Tóm tắt thông minh
Bluebird JS là một thư viện Promise đầy đủ tính năng dành cho... JavaTập lệnh có khả năng xác định là chuyển đổi thành promise: chuyển đổi các mô-đun Node dựa trên hàm gọi lại thành các mô-đun trả về promise, do đó toàn bộ thư viện như... MongoDB Trình điều khiển có thể được sử dụng bất đồng bộ.

Bluebird JS là gì?
Bluebird JS là một thư viện Promise đầy đủ tính năng dành cho... JavaScript. Tính năng mạnh nhất của nó là cho phép bạn "promisify" các module Node khác để sử dụng chúng bất đồng bộ. Promisify là một khái niệm được áp dụng cho các hàm gọi lại (callback functions), và nó đảm bảo rằng mọi hàm gọi lại được gọi đều trả về một giá trị.
Vì vậy, nếu một Node.js Module này chứa một hàm gọi lại không trả về giá trị, hứa hẹn rằng module sẽ tự động sửa đổi tất cả các hàm bên trong nó để mỗi hàm đều trả về một giá trị.
Điều này có nghĩa là bạn có thể sử dụng Bluebird để tạo ra MongoDB Module này chạy bất đồng bộ, giúp việc viết ứng dụng Node.js trở nên dễ dàng hơn.
Ví dụ dưới đây trước tiên thiết lập kết nối đến tập hợp “Employee” trong cơ sở dữ liệu “EmployeeDB”. Sau khi kết nối được thiết lập, nó sẽ truy xuất tất cả các bản ghi trong tập hợp và hiển thị chúng trong bảng điều khiển.
Cách tạo lời hứa với Thư viện Bluebird JS
Dưới đây là ví dụ từng bước hướng dẫn cách tạo promise bằng thư viện Bluebird JS.
Bước 1) Cài đặt các mô-đun NPM
Để sử dụng Bluebird từ bên trong một ứng dụng Node, cần phải cài đặt mô-đun Bluebird. Hãy cài đặt nó bằng lệnh sau:
npm install bluebird
Bước 2) Thêm mô-đun Bluebird
Bước tiếp theo là tích hợp mô-đun Bluebird vào mã của bạn và chuyển đổi toàn bộ thành Promise. MongoDB mô-đun. Từ "hứa hẹn" ở đây có nghĩa là Bluebird đảm bảo rằng mọi phương thức được định nghĩa trong mô-đun đều được thực thi. MongoDB thư viện trả lại một lời hứa.
Code Giải thích:
-
requireLệnh này bao gồm thư viện Bluebird. - Chim xanh
.promisifyAll()phương thức này tạo ra một phiên bản bất đồng bộ của mọi phương thức. MongoDB Mô-đun này cung cấp các hàm chạy ngầm và trả về một promise.
Bước 3) Kết nối với cơ sở dữ liệu
Bước cuối cùng là kết nối với cơ sở dữ liệu, truy xuất tất cả các bản ghi trong bộ sưu tập và hiển thị chúng trong nhật ký console.
Code Giải thích:
- Chú ý
connectAsyncphương pháp này được sử dụng thay cho phương pháp thông thường.connectphương pháp. Bluebird thêm vào Không đồng bộ hậu tố cho mỗi phương pháp trong MongoDB Thư viện này giúp phân biệt các lệnh gọi trả về promise với các lệnh gọi không trả về promise. Các phương thức không có hậu tố Async không đảm bảo điều này. - Tương tự như
connectAsync, CácfindAsyncPhương thức này trả về tất cả các bản ghi trong MongoDB Bộ sưu tập “Nhân viên”. - If
findAsyncNếu quá trình xử lý thành công, khối lệnh tiếp theo sẽ lặp qua từng bản ghi trong tập hợp và hiển thị chúng trong nhật ký console.
Nếu thực hiện đúng các bước trên, tất cả các tài liệu trong bộ sưu tập Nhân viên sẽ được hiển thị trong bảng điều khiển, như thể hiện trong kết quả bên dưới.
Dưới đây là toàn bộ mã nguồn để tham khảo:
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); }); });
⚠️ Lưu ý về phiên bản trình điều khiển: Đoạn mã trên nhắm đến mục tiêu MongoDB Trình điều khiển Node 2.x, trong đó connect Giải quyết bằng một đối tượng cơ sở dữ liệu. Từ trình điều khiển 3.0 trở đi nó được giải quyết bằng một MongoClient, vì vậy chuỗi phải gọi client.db('EmployeeDB').collection('Employee') thay vì db.collection('Employee')Các phiên bản trình điều khiển hiện đại cũng đã trả về các promise gốc, điều này giúp promisifyAll không cần thiết cho MongoDB đặc biệt.
Bluebird và Native Promises: Nên sử dụng cái nào?
Khi Bluebird được viết lần đầu, Node hoàn toàn không hỗ trợ promise, vì vậy thư viện này đã lấp đầy một khoảng trống thực sự trong nền tảng. Node đã tích hợp promise gốc từ phiên bản 4 trở lên. async/await Từ phiên bản 7.6 trở đi, cách tính toán sẽ thay đổi đáng kể đối với bất kỳ ai bắt đầu một dự án ngày nay.
| Yếu tố | Bluebird | Lời hứa bản địa |
|---|---|---|
| Phụ thuộc | Một gói npm để cài đặt và bảo trì. | Được tích hợp vào thời gian chạy |
| Hứa hẹn cuộc gọi lại | promisifyAll() chuyển đổi toàn bộ mô-đun |
util.promisify() chuyển đổi một hàm |
| Người trợ giúp thêm | bản đồ, bộ lọc, thuộc tính, từng, thời gian chờ, hủy bỏ | tất cả, tất cả đã định cư, bất kỳ, chỉ chủng tộc |
| Chồng dài traces | Có, khi được kích hoạt | Đã được cải tiến nhưng ngắn hơn. |
| Tốt nhất cho | Các thư viện gọi lại kế thừa, các công cụ hỗ trợ xử lý đồng thời | Mã mới và bất kỳ thứ gì sử dụng async await |
Hãy chọn native promises cho các dự án mới, vì chúng không cần phụ thuộc vào bất kỳ thư viện nào và tích hợp trực tiếp với async await. Sử dụng Bluebird khi thư viện đó vẫn chỉ cung cấp các hàm gọi lại (callbacks) hoặc khi cần các công cụ hỗ trợ xử lý đồng thời, chẳng hạn như... Promise.map Với giới hạn về số lượng xử lý đồng thời, bạn có thể tiết kiệm được một lượng mã đáng kể.
Cách xử lý lỗi với Bluebird Promises
Ví dụ trên không có đường dẫn lỗi. Nếu MongoDB Nếu quá trình không chạy, hoặc tên bộ sưu tập không chính xác, chuỗi sẽ bị từ chối và không có gì được in ra — tiến trình chỉ đơn giản là thoát mà không có lời giải thích. Mỗi chuỗi promise cần một trình xử lý cuối cùng.
Bluebird hỗ trợ .catch() đối với các lời từ chối và .finally() Để dọn dẹp những việc phải chạy dù thế nào đi nữa. Nó cũng hỗ trợ các catch kiểu dữ liệu, xử lý một loại lỗi trong khi cho phép các lỗi khác lan truyền.
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(); } });
Có ba thói quen quan trọng ở đây. Thứ nhất, hãy đặt đúng vị trí. .catch() Thứ nhất, ở cuối cùng chứ không phải sau mỗi bước, vì một trình xử lý đầu cuối nhận được thông báo từ chối từ mọi liên kết trước đó trong chuỗi. Thứ hai, hãy sử dụng .finally() Thứ nhất, để giải phóng các tài nguyên như kết nối cơ sở dữ liệu, vì nó chạy trên cả hai đường dẫn thành công và thất bại. Thứ hai, đừng bao giờ để lại một chuỗi mà không có cơ chế bắt lỗi: việc từ chối không được xử lý sẽ chấm dứt tiến trình Node trên các phiên bản hiện tại, và Bluebird sẽ in ra một cảnh báo rõ ràng về điều đó trước đó. Kích hoạt ngăn xếp dài traces trong quá trình phát triển với Promise.config({ longStackTraces: true }) Điều này giúp việc xác định nguyên nhân từ chối trở nên dễ dàng hơn nhiều.
Các lỗi thường gặp và cách khắc phục trong Bluebird Promisesify
Hầu hết các sự cố của Bluebird xuất phát từ quy ước đặt tên dựa trên Promise, hoặc từ việc trộn lẫn kiểu gọi hàm callback và Promise trong cùng một chuỗi, chứ không phải từ lỗi nào trong chính thư viện. Mỗi triệu chứng dưới đây đều nêu rõ nguyên nhân và cách khắc phục.
- “connectAsync không phải là một hàm”: Mô-đun này được yêu cầu trực tiếp thay vì thông qua
promisifyAll()Vì vậy, không có biến thể Async nào tồn tại. Hãy bao bọc lệnh gọi require như đã hiển thị ở trên. - Gọi phương thức thông thường và nhận được giá trị undefined:
connect()Nó vẫn mong đợi một hàm gọi lại. Chỉ có bản sao có hậu tố Async mới trả về một promise. - Truyền hàm callback cho một phương thức Async: không cung cấp hàm gọi lại cũng không
awaitvà lời hứa được giải quyết mà không được ghi nhận. Hãy sử dụng một kiểu cho mỗi lần gọi, không sử dụng cả hai. - promiseifyAll trên một thư viện đã dựa trên promise: Vô hại nhưng vô nghĩa, và nó tạo ra những tên có hậu tố kép gây nhầm lẫn. Hãy kiểm tra tài liệu thư viện trước.
- Những lỗi xảy ra âm thầm: một chuỗi không có
.catch()Ẩn lý do từ chối cho đến khi Node báo cáo lỗi từ chối không được xử lý và thoát. Luôn kết thúc chuỗi bằng một khối catch, ngay cả trong các đoạn mã ngắn.



