Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Aufheben der Verschachtelung von Node-Datenbankaufrufen

Sie können verschachtelte Datenbankaufrufe loswerden, indem Sie Versprechen .

Da Sie erwähnt haben, dass Sie mysql verwenden Bibliothek für die Interaktion mit der Datenbank, leider bietet diese Bibliothek keine Promise-basierte API. Um also verschachtelte Datenbankaufrufe in Ihrem Code loszuwerden, müssen Sie einen Promise-basierten Wrapper um die Callback-Version von Datenbankaufrufen erstellen.

Einen allgemeinen Überblick darüber, was Zusagen sind und wie sie funktionieren, finden Sie unter den folgenden Links:

Im Folgenden finden Sie ein Beispiel dafür, wie Sie einen Promise-basierten Wrapper erstellen und diesen Wrapper dann verwenden können, um verschachtelte Datenbankaufrufe loszuwerden.

Dieser Promise-basierte Wrapper ist nur eine Funktion, die ein Promise zurückgibt. Es erstellt eine Promise-Instanz, umschließt den zugrunde liegenden Datenbankaufruf und schließlich, wenn der Datenbankaufruf die Daten zurückgibt, benachrichtigt es Ihren Code.

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);
       });
   });
}

Jetzt in Ihrer Route-Handler-Funktion, anstatt db.cats(...) aufzurufen , nennen Sie dies getCats Wrapper-Funktion.

Es gibt zwei Möglichkeiten, die Funktion aufzurufen, die ein Promise zurückgibt:

  • Promise-Chaining (Weitere Informationen finden Sie unter den oben genannten Links)
  • async-await Syntax (empfohlen)

Das folgende Codebeispiel verwendet async-await Syntax. Markieren Sie dazu zunächst die Route-Handler-Funktion als async indem Sie async verwenden Schlüsselwort vor function Stichwort. Dazu können wir await verwenden Schlüsselwort innerhalb dieser Route-Handler-Funktion.

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
     }
});

Das obige Codebeispiel zeigt nur, wie man db.cats(...) umschließt database einen Promise-basierten Wrapper aufrufen und diesen Wrapper verwenden, um die Daten aus der Datenbank abzurufen. Ebenso können Sie Wrapper für db.dogs(...) erstellen und db.budgies(...) Anrufe.

Anstatt für jeden Datenbankaufruf einen separaten Promise-basierten Wrapper zu erstellen, sollten Sie idealerweise eine wiederverwendbare Promise-basierte Wrapper-Funktion erstellen das eine aufzurufende Funktion aufnimmt und diesen Funktionsaufruf in ein Promise verpackt, genau wie im obigen Codebeispiel gezeigt, d. h. getCats Funktion.

Parallele Datenbankaufrufe

Eine wichtige Sache, die im obigen Code in der Route-Handler-Funktion zu beachten ist

const cats = await getCats();
const dogs = await getDogs();
const budgies = await getBudgies();

ist, dass dies zu sequentiellen Datenbankaufrufen führt das kann oder kann nicht, was Sie wollen.

Wenn diese Datenbankaufrufe nicht voneinander abhängen, können Sie die Promise-basierten Wrapper parallel mit Promise.all() Methode.

Das folgende Codebeispiel zeigt, wie Sie Ihre Promise-basierten Wrapper-Funktionen mit Promise.all() parallel aufrufen können .

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) {
       ...
     }
 });

Ich hoffe, das reicht aus, um Ihnen dabei zu helfen, die verschachtelten Datenbankaufrufe in Ihrem aktuellen Code loszuwerden und mit der Verwendung von Promises in Ihrem Code zu beginnen.