Expressでawaitしているのに非同期処理されてしまう

#現状
ログイン処理の作成中、postされたユーザ情報を元にDBベースに検索をかけてパスワードのチェックをして結果を返すはずが、結果を待たずundefinedを返してしまいます。

#問題のコード
まずは、Expressのポストを受けつける部分です。

```javascript:index.js
    app.post('/signup', async (req, res, next) => {
        try {
            var controler = new AccountControler(dbcontroler);
            var result = await controler.signup(req.body);
            logging.logger.debug(result);
            res.json(result);
        } catch(error) {
            next(error)
        }
    });
```
ログイン処理を行うAccountControlerのsignupメソッドをawaitでコールしています。
また、その結果をコンソールにログとして吐き出しています。

```javascript:AccountControler.js
    async getLoginSuccessMessage(res) {
        return {
            success: true,
            token: await jwt.sign(
                {
                    userid: res.userid,
                    authtime: moment().format()
                }, 
                publickey
            ),
            userinfo: {
                username: res.username
            }
        }
    }

    async signup(data) {

        try {
            data = JSON.parse(JSON.stringify(data));
            // DBからユーザ情報を取得
            var res =  await this.dbcontroler.selectRecode(
                this.LoginUserViewModel.getSelectSqlOfLoginUser(data.loginuser.loginid),
                (res) => this.LoginUserViewModel.serializerFromDatabase(res));

            if (res.length == 0) {
                return this.getLoginFailedMessage();
            } else {
                // パスワードが一致しているかチェック
                return await bcrypt.compare(data.loginuser.loginpassword, res[0].loginpassword, async (err, result) => {
                    if (err) {
                        this.logger.debug(err);
                        return await this.getLoginFailedMessage();
                    } else if (result) {
　　　　　　　　　　　　　// ログ出力
                        this.logger.debug('result is' + JSON.stringify(await this.getLoginSuccessMessage(res)));
                        // ログイン可能時に返却するデータを生成
                        return await this.getLoginSuccessMessage(res);
                    } else {
                        return await this.getLoginFailedMessage();
                    }
                })
            }

        } catch (error) {
            this.logger.debug(error);
            throw error;
        }
    }

```
いくつか処理を行っていますが、
①ログインIDをキーにDBからユーザ情報を取得（コールバック使用）
②bcryptでハッシュ化されたパスワードと受信したパスワードを比較（コールバック使用）
③結果をjwtでユーザ情報に関する情報を暗号化

上記のような感じで全てawaitを使用しています。

```console:ログ
[2019-09-03T10:03:09.072] [DEBUG] default - undefined
[2019-09-03T10:03:09.216] [DEBUG] default - result is{"success":true,"token":"eyJhbGcU...
```

長いので少し省略していますが、分かりにくいログですが、１行目が最初のコードのログ出力で、次が２つめのコードのログ出力内容です。
最初のコードでawaitが待ってくれず、処理されているように思えます。

#修正内容１
一応Expressが同期処理に対応しているかの確認も含めて、以下をチェックしました

[Express公式：Use promises](http://expressjs.com/en/advanced/best-practice-performance.html#use-promises)

とりあえず、promise形式に変更してみました。

```javascript:index.js
    app.post('/signup', (req, res, next) => {
        var controler = new AccountControler(dbcontroler);
        controler.signup(req.body)
        .then((d) => {
            logging.logger.debug(d);
            res.json(d)
        })
        .catch((error) => next(error));
    });
```
結果はかわらず

#修正内容２
上記の変更はのままに、コール側の処理も合わせてPromiseに変更しました

```javascript:AccountControler.js
    async signup(data) {

        return new Promise((resolve, reject) => {
            data = JSON.parse(JSON.stringify(data));
    
            this.logger.debug(JSON.stringify(data))

            this.dbcontroler.selectRecode(
                this.LoginUserViewModel.getSelectSqlOfLoginUser(data.loginuser.loginid),
                (res) => this.LoginUserViewModel.serializerFromDatabase(res))
            .then((res) => {
                if (res.length == 0) {
                    return this.getLoginFailedMessage();
                } else {
                    bcrypt.compare(data.loginuser.loginpassword, res[0].loginpassword)
                    .then( async (result) => {
                        if (result) {
                            this.logger.debug('result is' + JSON.stringify(await this.getLoginSuccessMessage(res)));
                            resolve(await this.getLoginSuccessMessage(res));
                        } else {
                            resolve(await this.getLoginFailedMessage());
                        }

                    })
                    .catch((error) => {
                        this.logger.debug(error);
                        reject(error)
                    })
                    
                }
    
            })
            .catch((error) =>{ 
                this.logger.debug(error);
                reject(error);
            })
        });
    }
```
結果、うまく動作しました。ログは下記の通りです。

```console:ログ
[2019-09-03T11:45:41.723] [DEBUG] default - result is{"success":true,"token":"eyJhbGciOiJ...
[2019-09-03T11:45:41.724] [DEBUG] default - { success: true,token:'eyJhb...
```

#結論
最終的に期待通りに動作はしました。しかし、なぜ動作したのか解っていません。
（私のasync/awaitの使い方が悪いということかも知れません。多分そんなことだと思いますが…）
解るのは、他も全部修正ということだけです…

ちなみに私は、下記を参考にプロジェクトを生成しています。
[Vue-CLI3 ベースのアプリ開発で JSON API が使える express server を使う](https://qiita.com/corestate55/items/81ba50cf33c78b7119fd)

簡単に作成方法を記載すると、

```console:
$vue create prpjectname
$vue add express
```
上記でvue-cli-plugin-expressがインストールされるようです。

バージョンは下記の通りです。

```console
$npm view express version
4.17.1
$npm view vue-cli-plugin-express version
1.0.2
```
バージョンは現時点では最新のようです。
vue-cliを用いずExpressを使用した場合、このような動作を行うか分かりません。
残念ながら試すのも困難（面倒…）なのでここまでです。

この方法がベスト（スタンダード？）なのか、どうなのか気になります。
知っている方はコメントして頂けると、私の気持ちがスッキリするのでコメントしてください。

#再修正
コメント頂きました！ありがとうございます。

ということで、大本のソースの状態に戻した上で、下記のように修正を行いました。

```javascript:AccountControler.js
    async signup(data) {


        try {
            data = JSON.parse(JSON.stringify(data));

            this.logger.debug(JSON.stringify(data))

            var res =  await this.dbcontroler.selectRecode(
                this.LoginUserViewModel.getSelectSqlOfLoginUser(data.loginuser.loginid),
                (res) => this.LoginUserViewModel.serializerFromDatabase(res));

            if (res.length == 0) {
                return this.getLoginFailedMessage();
            } else {
                // 修正は以下の部分でcallbackを取りやめました
                const result = await bcrypt.compare(data.loginuser.loginpassword, res[0].loginpassword);

                if (result) {
                    this.logger.debug('result is' + JSON.stringify(await this.getLoginSuccessMessage(res)));
                    return await this.getLoginSuccessMessage(res);
                } else {
                    return await this.getLoginFailedMessage();
                }

            }

        } catch (error) {
            this.logger.debug(error);
            throw error;
        }
    }

```
上記の結果、期待通りに動作致しました！

コメント頂いた下記からの抜粋です。
[bcrypt](https://www.npmjs.com/package/bcrypt)

>Async methods that accept a callback, return a Promise when callback is not specified if Promise support is available.

callbackを指定しなければ、Promiseを返すと書かれていますね。
やはり、私の書き方が悪かったようです。でも、スッキリしました。