我在设置结果对象的控制器中有一个异步方法。问题在于,不是等待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();
不要将async
/ await
直接与基于回调的API混合。
根据the documentation,mongoose.connect
does返回一个promise(假设您使用的是最新版本),但是没有任何建议表明它使promise等待回调中发生的事情你给它。
相反,在await mongoose.connect
之后的代码中执行这些操作。