Mysql
 sql >> Database >  >> RDS >> Mysql

Chiamate al database di unnesting Node

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.