Anda dapat menyingkirkan panggilan database bersarang dengan menggunakan promises
.
Karena Anda menyebutkan bahwa Anda menggunakan mysql
library untuk berinteraksi dengan database, sayangnya library ini tidak menyediakan API berbasis janji. Jadi untuk menghilangkan panggilan database bersarang dalam kode Anda, Anda perlu membuat pembungkus berbasis janji di sekitar versi panggilan balik panggilan database.
Untuk gambaran umum tentang apa itu janji dan cara kerjanya, lihat tautan berikut:
Berikut adalah contoh bagaimana Anda bisa membuat pembungkus berbasis janji dan kemudian menggunakan pembungkus itu untuk menyingkirkan panggilan database bersarang.
Pembungkus berbasis janji ini hanyalah fungsi yang mengembalikan janji. Ini membuat instance janji, membungkus panggilan basis data yang mendasarinya dan akhirnya ketika panggilan basis data mengembalikan data, ia memberi tahu kode Anda.
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);
});
});
}
Sekarang dalam fungsi pengendali rute Anda, alih-alih memanggil db.cats(...)
, panggil ini getCats
fungsi pembungkus.
Ada dua cara Anda dapat memanggil fungsi yang mengembalikan janji:
Promise-chaining
(Untuk detailnya, kunjungi tautan yang disebutkan di atas)async-await
sintaks (Disarankan)
Contoh kode berikut menggunakan async-await
sintaksis. Untuk ini, pertama tandai fungsi pengendali rute sebagai async
dengan menggunakan async
kata kunci sebelum function
kata kunci. Untuk melakukan ini, kita dapat menggunakan await
kata kunci di dalam fungsi pengendali rute ini.
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
}
});
Contoh kode di atas hanya menunjukkan cara membungkus db.cats(...)
panggilan database dalam pembungkus berbasis janji dan gunakan pembungkus itu untuk mendapatkan data dari database. Demikian pula, Anda dapat membuat pembungkus untuk db.dogs(...)
dan db.budgies(...)
panggilan.
Daripada membuat pembungkus berbasis janji yang terpisah untuk setiap panggilan database, idealnya, Anda harus membuat fungsi pembungkus berbasis janji yang dapat digunakan kembali yang mengambil fungsi untuk memanggil dan membungkus panggilan fungsi itu dalam janji seperti yang ditunjukkan pada contoh kode di atas, yaitu getCats
fungsi.
Panggilan Database Paralel
Satu hal penting yang perlu diperhatikan pada kode di atas pada fungsi route handler
const cats = await getCats();
const dogs = await getDogs();
const budgies = await getBudgies();
adalah bahwa ini akan mengarah ke panggilan database berurutan yang mungkin atau mungkin tidak seperti yang Anda inginkan.
Jika panggilan basis data ini tidak bergantung satu sama lain, Anda dapat memanggil pembungkus berbasis janji secara paralel menggunakan Promise.all()
metode.
Contoh kode berikut menunjukkan bagaimana Anda dapat memanggil fungsi pembungkus berbasis janji Anda secara paralel menggunakan 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) {
...
}
});
Saya harap ini cukup untuk membantu Anda menyingkirkan panggilan database bersarang dalam kode Anda saat ini dan mulai menggunakan janji dalam kode Anda.