web-dev-qa-db-ja.com

Express JSはリクエストで非同期機能を使用します

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側でいくつかの問題を引き起こす可能性があることを恐れています。

6
Anton Stafeyev

非同期待機は、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
})
0

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

非同期関数を使用してDBクエリの待機を使用できるようにすることは、まったく問題ありません。ただし、そのコードをtryおよびcatchブロックに埋め込んで、例外をキャッチできるようにしてください。

0
Zeeshan Tariq