<を使用すると、ネストされたデータベース呼び出しを取り除くことができます。 code>約束 。
mysql
を使用しているとおっしゃっていたので
データベースと対話するためのライブラリですが、残念ながら、このライブラリはPromiseベースのAPIを提供していません。したがって、コード内のネストされたデータベース呼び出しを取り除くには、データベース呼び出しのコールバックバージョンの周りにpromiseベースのラッパーを作成する必要があります。
約束とは何か、そしてそれらがどのように機能するかの一般的な概要については、次のリンクを参照してください。
以下は、Promiseベースのラッパーを作成し、そのラッパーを使用してネストされたデータベース呼び出しを削除する方法の例です。
このpromiseベースのラッパーは、promiseを返す関数にすぎません。これは、promiseインスタンスを作成し、基になるデータベース呼び出しをラップし、最終的にデータベース呼び出しがデータを返すときに、コードに通知します。
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
と呼びます ラッパー関数。
promiseを返す関数を呼び出す方法は2つあります。
約束の連鎖
(詳細については、上記のリンクをご覧ください)-
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(...)
をラップする方法のみを示しています。 データベースはpromiseベースのラッパーを呼び出し、そのラッパーを使用してデータベースからデータを取得します。同様に、 db.dogs(...)
のラッパーを作成できます およびdb.budgies(...)
呼び出します。
データベース呼び出しごとに個別のpromiseベースのラッパーを作成する代わりに、理想的には、再利用可能なpromiseベースのラッパー関数を作成する必要があります これは、呼び出す関数を取り込んで、上記のコード例に示されているように、その関数呼び出しをpromiseでラップします。つまり、 getCats
機能。
並列データベース呼び出し
上記のルートハンドラー関数のコードで注意すべき重要な点の1つ
const cats = await getCats();
const dogs = await getDogs();
const budgies = await getBudgies();
これにより、データベースの順次呼び出しが発生します。 これはあなたが望むものかもしれないし、そうでないかもしれません。
これらのデータベース呼び出しが相互に依存していない場合は、 Promise.all()
メソッド。
次のコード例は、 Promise.all()
を使用してpromiseベースのラッパー関数を並列に呼び出す方法を示しています。 。
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) {
...
}
});
これで、現在のコードでネストされたデータベース呼び出しを取り除き、コードでpromiseの使用を開始するのに十分であることを願っています。