app.use(async function(req, res, next) {
try {
var myres = await new Promise((resolve, reject) => {
mysql_connection.query("select * from Users;", (err, rows) => {
if (err) {
reject(err);
} else {
resolve(rows);
}
});
});
} catch (error) {
console.log(error);
}
});
質問です。非同期関数を使用してDBクエリを待つことはできますか?私はそれがexpressjs側でいくつかの問題を引き起こす可能性があることを恐れています。
非同期待機は、DBクエリに問題なく使用できます。 try catchを使用することもできますが、提供するエラー処理ミドルウェアを使用できる、よりエレガントなソリューションがあります。
この関数でミドルウェアをラップします。
const asyncMiddleware = fn =>
(req, res, next) => {
Promise.resolve(fn(req, res, next))
.catch(next);
};
その後、次のように使用できます。
const asyncMiddleware = require('./utils/asyncMiddleware');
router.get('/', asyncMiddleware(async (req, res, next) => {
/*
if there is an error thrown in getUserFromDb, asyncMiddleware
will pass it to next() and express will handle the error;
*/
const user = await getUserFromDb({ id: req.params.id })
res.json(user);
}));
エラーがスローされると、コントロールは、次のような4つの引数を持つミドルウェアであるエラー処理ミドルウェアに渡されます。
app.use(function (err, req, res, next) {
// your error code
})
async..await
はpromiseの構文糖であり、promiseはコールバックに依存する単なるパターンです。 async
関数の使用は、環境でサポートされている場所であればどこでも使用できます。 async..await
はNode.js 7.6.0以降でサポートされています。
async
関数は常にpromiseを返します。この暗黙の戻り値が問題を引き起こさない限り、Expressを含むすべての場所で問題はありません。データベースクエリに使用されるか、それ以外に使用されるかは関係ありません。
APIがpromiseをサポートしていない限り、エラーはasync
関数で完全に処理する必要があります。関数本体をtry..catch
でラップして、未処理の拒否を除外し、将来的に例外が発生する可能性があるNodeバージョン。
元のコードにはnext
呼び出しが含まれておらず、エラーを抑制するだけです。経験則として、async
ミドルウェアは次のように構成する必要があります。
app.use(async function(req, res, next) {
try {
...
next();
} catch (error) {
next(error);
}
});
非同期関数を使用してDBクエリの待機を使用できるようにすることは、まったく問題ありません。ただし、そのコードをtryおよびcatchブロックに埋め込んで、例外をキャッチできるようにしてください。