Bạn có thể loại bỏ các lệnh gọi cơ sở dữ liệu lồng nhau bằng cách sử dụng lời hứa
.
Vì bạn đã đề cập rằng bạn đang sử dụng mysql
thư viện để tương tác với cơ sở dữ liệu, rất tiếc, thư viện này không cung cấp một API dựa trên lời hứa. Vì vậy, để loại bỏ các lệnh gọi cơ sở dữ liệu lồng nhau trong mã của bạn, bạn cần tạo một trình bao bọc dựa trên lời hứa xung quanh phiên bản gọi lại của các lệnh gọi cơ sở dữ liệu.
Để biết tổng quan chung về lời hứa là gì và cách chúng hoạt động, hãy xem các liên kết sau:
Sau đây là một ví dụ về cách bạn có thể tạo trình bao bọc dựa trên lời hứa và sau đó sử dụng trình bao bọc đó để loại bỏ các lệnh gọi cơ sở dữ liệu lồng nhau.
Trình bao bọc dựa trên lời hứa này chỉ là một hàm trả về một lời hứa. Nó tạo một cá thể lời hứa, kết thúc cuộc gọi cơ sở dữ liệu bên dưới và cuối cùng khi lệnh gọi cơ sở dữ liệu trả về dữ liệu, nó sẽ thông báo mã của bạn.
function getCats() {
return new Promise((resolve, reject) => {
// make the database call
db.cats((error, cats) => {
// in case of an error, reject the promise by
// calling "reject" function
// Also pass the "error" object to the "reject" function
// as an argument to get access to the error message
// in the code that calls this "getCats" function
if (error) {
reject(error);
return;
}
// if there was no error, call "resolve" function
// to resolve the promise. Promise will be resolved
// in case of successful database call
// Also pass the data to "resolve" function
// to access this data in the code that calls this
// "getCats" function
resolve(cats);
});
});
}
Bây giờ trong hàm xử lý tuyến đường của bạn, thay vì gọi db.cats (...)
, gọi đây là getCats
chức năng trình bao bọc.
Có hai cách bạn có thể gọi hàm trả về một lời hứa:
-
Promise-chain
(Để biết chi tiết, hãy truy cập các liên kết được đề cập ở trên) -
async-await
cú pháp (Khuyến nghị)
Ví dụ mã sau sử dụng async-await
cú pháp. Đối với điều này, trước tiên hãy đánh dấu hàm xử lý định tuyến là async
bằng cách sử dụng async
từ khóa trước hàm
từ khóa. Làm điều này, chúng ta có thể sử dụng await
từ khóa bên trong hàm xử lý tuyến đường này.
app.get('/pets', async function(req, res, next) {
try {
const cats = await getCats();
// similar wrappers for other database calls
const dogs = await getDogs();
const budgies = await getBudgies();
// render the pub template, passing in the data
// fetched from the database
...
catch (error) {
// catch block will be invoked if the promise returned by
// the promise-based wrapper function is rejected
// handle the error appropriately
}
});
Ví dụ mã trên chỉ hiển thị cách quấn db.cats (...)
gọi cơ sở dữ liệu trong một trình bao bọc dựa trên lời hứa và sử dụng trình bao bọc đó để lấy dữ liệu từ cơ sở dữ liệu. Tương tự, bạn có thể tạo trình bao bọc cho db.dogs (...)
và db.budgies (...)
cuộc gọi.
Thay vì tạo một trình bao bọc dựa trên lời hứa riêng biệt cho mỗi lệnh gọi cơ sở dữ liệu, lý tưởng là bạn nên tạo một chức năng trình bao bọc dựa trên lời hứa có thể tái sử dụng nhận một hàm để gọi và kết thúc lệnh gọi hàm đó trong một lời hứa giống như được hiển thị trong ví dụ mã ở trên, tức là getCats
chức năng.
Lệnh gọi cơ sở dữ liệu song song
Một điều quan trọng cần lưu ý trong đoạn mã trên trong hàm xử lý tuyến đường
const cats = await getCats();
const dogs = await getDogs();
const budgies = await getBudgies();
là điều này sẽ dẫn đến lệnh gọi cơ sở dữ liệu tuần tự cái mà bạn có thể muốn hoặc không.
Nếu các lệnh gọi cơ sở dữ liệu này không phụ thuộc vào nhau, thì bạn có thể gọi song song các trình bao bọc dựa trên lời hứa bằng cách sử dụng Promise.all ()
phương pháp.
Ví dụ mã sau đây cho thấy cách bạn có thể gọi các hàm trình bao bọc dựa trên lời hứa của mình song song bằng cách sử dụng Promise.all ()
.
app.get('/pets', async function(req, res, next) {
try {
// "petsData" will be an array that will contain all the data from
// three database calls.
const petsData = await Promise.all([getCats(), getDogs(), getBudgies()]);
// render the pub template, passing in the data
// fetched from the database
...
catch (error) {
...
}
});
Tôi hy vọng điều này đủ để giúp bạn loại bỏ các lệnh gọi cơ sở dữ liệu lồng nhau trong mã hiện tại của bạn và bắt đầu sử dụng các hứa hẹn trong mã của bạn.