Можете да се отървете от вложени извиквания на база данни, като използвате обещания
.
Тъй като споменахте, че използвате mysql
библиотека за взаимодействие с базата данни, за съжаление, тази библиотека не предоставя API, базиран на обещания. Така че, за да се отървете от вложените извиквания на база данни във вашия код, трябва да създадете обвивка, базирана на обещания, около версията за обратно извикване на извикванията към базата данни.
За общ преглед на това какво представляват обещанията и как работят, вижте следните връзки:
Следва пример за това как можете да създадете обвивка, базирана на обещания, и след това да използвате тази обвивка, за да се отървете от вложени извиквания на база данни.
Тази обвивка, базирана на обещания, е просто функция, която връща обещание. Той създава екземпляр на обещание, обвива основното извикване на базата данни и в крайна сметка, когато извикването на базата данни върне данните, то уведомява вашия код.
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);
});
});
}
Сега във вашата функция за обработка на маршрути, вместо да извиквате db.cats(...)
, извикайте това getCats
функция за обвивка.
Има два начина, по които можете да извикате функцията, която връща обещание:
Веригиране на обещания
(За подробности посетете посочените по-горе връзки)async-await
синтаксис (препоръчително)
Следващият пример за код използва async-await
синтаксис. За това първо маркирайте функцията за обработка на маршрут като async
с помощта на async
ключова дума преди функцията
ключова дума. Правейки това, можем да използваме await
ключова дума в тази функция за обработка на маршрути.
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
}
});
Примерът с кода по-горе показва само как да обвиете db.cats(...)
извикване на база данни в обвивка, базирана на обещания, и използвайте тази обвивка, за да получите данните от базата данни. По подобен начин можете да създадете обвивки за db.dogs(...)
и db.budgies(...)
обаждания.
Вместо да създавате отделна обвивка, базирана на обещания, за всяко извикване на база данни, в идеалния случай трябва да създадете повторно използваема функция за обвивка, базирана на обещания който приема функция за извикване и обвива това извикване на функция в обещание, точно както е показано в горния пример с код, т.е. getCats
функция.
Паралелни извиквания на база данни
Едно важно нещо, което трябва да се отбележи в горния код във функцията за обработка на маршрут
const cats = await getCats();
const dogs = await getDogs();
const budgies = await getBudgies();
е, че това ще доведе до последователни извиквания на база данни което може или не е това, което искате.
Ако тези извиквания на база данни не зависят едно от друго, тогава можете да извикате успоредно базираните на обещания обвивки, като използвате Promise.all()
метод.
Следващият пример с код показва как можете да извикате паралелно своите базирани на обещания обвиващи функции, като използвате 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) {
...
}
});
Надявам се това да е достатъчно, за да ви помогне да се отървете от вложените извиквания на база данни в текущия си код и да започнете да използвате обещания в кода си.