Puoi eliminare le chiamate nidificate al database utilizzando promises
.
Poiché hai menzionato che stai utilizzando mysql
libreria per interagire con il database, sfortunatamente questa libreria non fornisce un'API basata su promesse. Quindi, per eliminare le chiamate al database nidificate nel codice, devi creare un wrapper basato su promesse attorno alla versione di callback delle chiamate al database.
Per una panoramica generale di cosa sono le promesse e come funzionano, vedere i seguenti collegamenti:
Di seguito è riportato un esempio di come creare un wrapper basato su promesse e quindi utilizzarlo per eliminare le chiamate nidificate al database.
Questo wrapper basato su promesse è solo una funzione che restituisce una promessa. Crea un'istanza di promessa, esegue il wrapping della chiamata al database sottostante e, infine, quando la chiamata al database restituisce i dati, notifica il tuo codice.
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);
});
});
}
Ora nella tua funzione di gestione del percorso, invece di chiamare db.cats(...)
, chiama questo getCats
funzione wrapper.
Esistono due modi per chiamare la funzione che restituisce una promessa:
Promise-chaining
(Per i dettagli, visitare i link sopra menzionati)async-await
sintassi (consigliato)
L'esempio di codice seguente utilizza async-await
sintassi. Per questo, contrassegna prima la funzione del gestore di route come async
utilizzando async
prima della function
parola chiave. In questo modo, possiamo utilizzare await
parola chiave all'interno di questa funzione di gestione del percorso.
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
}
});
L'esempio di codice sopra mostra solo come eseguire il wrapping di db.cats(...)
chiamata al database in un wrapper basato su promesse e utilizzare quel wrapper per ottenere i dati dal database. Allo stesso modo, puoi creare wrapper per db.dogs(...)
e db.budgies(...)
chiamate.
Invece di creare un wrapper basato sulla promessa separato per ogni chiamata al database, idealmente, dovresti creare una funzione wrapper basata sulla promessa riutilizzabile che accetta una funzione da chiamare e racchiude quella chiamata di funzione in una promessa, proprio come mostrato nell'esempio di codice sopra, ovvero getCats
funzione.
Chiamate database parallele
Una cosa importante da notare nel codice sopra nella funzione di gestione del percorso
const cats = await getCats();
const dogs = await getDogs();
const budgies = await getBudgies();
è che questo porterà a chiamate sequenziali al database che può o non può quello che vuoi.
Se queste chiamate al database non dipendono l'una dall'altra, puoi chiamare i wrapper basati su promesse in parallelo usando Promise.all()
metodo.
L'esempio di codice seguente mostra come chiamare le funzioni wrapper basate su promesse in parallelo usando 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) {
...
}
});
Spero che questo sia sufficiente per aiutarti a sbarazzarti delle chiamate nidificate al database nel tuo codice corrente e iniziare a utilizzare le promesse nel tuo codice.