TypeScript API中的异步等待被跳过

问题描述 投票:0回答:1

我在设置结果对象的控制器中有一个异步方法。问题在于,不是等待await完成执行,而是跳转到响应对象调用,该调用使所需的变量未定义。在调试器中,应该执行的方法中的断点在未定义的错误之后被命中。谁能解释为什么异步等待在这里不起作用?

控制器类中的方法:

public async loginUser(req: Request, res: Response) {
    const { name, password } = req.body;
    let result: ILoginResult = await UserData.login(name, password); // always undefined
    res.status(result.status).send(result.result); // gets hit before result is set
  }

UserData类:

import bcrypt from 'bcrypt';
import jwt from 'jsonwebtoken';
import mongoose from 'mongoose';
import ILoginResult from './ILoginResult';
import UserModel from '../../models/UserModel';

class UserData {
    private connUri: string;

    constructor() {
        this.connUri = process.env.MONGO_LOCAL_CONN_URL;
    }

    public async login(name: string, password: string) {

        try {
            await mongoose.connect(this.connUri, { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true, }, (err) => {
                let result: ILoginResult = { status: 0, result: null, error: '', token: '' };
                let status = 200;
                if (!err) {
                    UserModel.findOne({ name }, (err, user) => {
                        if (!err && user) {
                            // We could compare passwords in our model instead of below as well
                            bcrypt.compare(password, user.password).then(match => {
                                if (match) {
                                    status = 200;
                                    // Create a token
                                    const payload = { user: user.name };
                                    const options = { expiresIn: '2d', issuer: 'http://localhost' };
                                    const secret = process.env.JWT_SECRET;
                                    const token = jwt.sign(payload, secret, options);

                                    // console.log('TOKEN', token);
                                    result.token = token;
                                    result.status = status;
                                    result.result = user;
                                } else {
                                    status = 401;
                                    result.status = status;
                                    result.error = `Authentication error`;
                                }
                                return result;
                            }).catch(err => {
                                status = 500;
                                result.status = status;
                                result.error = err;
                                return { status: status, result: result };
                            });
                        } else {
                            status = 404;
                            result.status = status;
                            result.error = err;
                            return result;
                        }
                    });
                } else {
                    status = 500;
                    result.status = status;
                    result.error = err.toString();
                    return result;
                }
            });
        } catch (e) {
            let result: ILoginResult;
            result.error = e.toString();
            result.status = 500;
            return result;
        }
    }
}

export default new UserData();
javascript typescript rest
1个回答
0
投票

不要将async / await直接与基于回调的API混合。

根据the documentationmongoose.connect does返回一个promise(假设您使用的是最新版本),但是没有任何建议表明它使promise等待回调中发生的事情你给它。

相反,在await mongoose.connect之后的代码中执行这些操作。

© www.soinside.com 2019 - 2024. All rights reserved.