我在做Promises错误...我在这里想念什么? [英] I'm doing Promises wrong... What am I missing here?
问题描述
我有一个文件 token.ts ,该文件可以导出1个功能:
I have a file token.ts that exports 1 function:
import * as jwt from 'jsonwebtoken';
import { db, dbUserLevel } from '../util/db';
export function genToken(username, password): Object {
let token: Object;
let token_payload = { user: username, admin: false };
let token_payload_admin = { user: username, admin: true };
// TODO: Add secret as an environment variable and retrieve it from there
let token_secret = 'move this secret somewhere else';
let token_header = {
issuer: 'SomeIssuer',
algorithm: 'HS256',
expiresIn: '1h'
};
db.open().then(() => { dbUserLevel('admin') }).then(() => {
db.collection('users').findOne({ username: username, password: password })
.then((result) => {
if (result.isAdmin === 1) {
this.token = { access_token: jwt.sign(token_payload_admin, token_secret, token_header) }
} else if (result.isAdmin === 0) {
this.token = { access_token: jwt.sign(token_payload, token_secret, token_header) }
}
db.close();
})
})
return this.token;
};
我还有另一个文件 login.ts ,该文件从token.ts文件中导入了genToken函数:
I have another file login.ts which imports the genToken function from the token.ts file:
import { Router } from 'express-tsc';
import { db, dbUserLevel } from '../../util/db';
import * as bodyParser from 'body-parser';
import { genToken } from '../../util/token';
import * as jwt from 'jsonwebtoken';
export var router = Router();
let urlencodedParser = bodyParser.urlencoded({ extended: false });
let jsonParser = bodyParser.json();
router.post('/', jsonParser, (req, res) => {
req.accepts(['json', 'text/plain']);
let data = req.body;
console.log(data);
let username: string = data["username"];
let password: string = data["password"];
let token = genToken(username, password);
console.log(JSON.stringify(token));
res.send(200, token);
});
应该发生的是,当我从login.ts文件提交表单时,它将响应发送到服务器并调用该genToken(username,password)函数并返回令牌Object.
What is supposed to happen is when I submit the form from my login.ts file, it will post the response to server and call that genToken(username, password) function and return the token Object.
由于某些原因,不确定为什么当我第一次提交表单时,"token"(login.ts)是未定义的.如果我再次提交表单,那么令牌对象将返回并按预期方式登录到控制台....
For some reason, not sure why, when I submit the form the first time, "token" (login.ts) is undefined. If I submit the form again, then token Object is returned and logged to console as expected....
有人知道为什么会这样吗?如果我没有提供足够的信息,请告诉我您可能需要什么,以便我可以更新该帖子!谢谢!
Anyone know why this might be? If I have not included enough information, please let me know what you might need so I can update the post! Thanks!
编辑
根据接受的答案中提供的信息,我提出了以下解决我最初问题的更改:
Based on the info provided in the accepted answer, I came up with the following changes that have addressed my initial problem:
token.ts:
...
let token: Object;
let query = db.open()
.then(() => dbUserLevel('user'))
.then(() => db.collection('users').findOne({ username: username, password: password })
.then((result) => {
if (result.isAdmin === 1) {
token = { access_token: jwt.sign(token_payload_admin, token_secret, token_header) }
} else if (result.isAdmin === 0) {
token = { access_token: jwt.sign(token_payload, token_secret, token_header) }
}
})
.catch(err => {
db.close();
Promise.reject(err);
}))
.then(() => {
db.close();
Promise.resolve(token);
return token;
})
.catch(err => {
db.close();
Promise.reject(err);
return err;
});
return query;
};
login.ts:
...
genToken(username, password)
.then(token => {
res.status(200).send(token);
})
.catch(err => {
res.status(500).send(err);
});
});
推荐答案
据我所知,您遇到的问题是,当您尝试以同步方式读取令牌时,令牌是以异步方式生成的道路.
As far as I can see, the issue that you are experiencing is that the token is generated in an async manner while you are trying to read it in a sync way.
您的genToken方法应该返回一个Promise,并且一旦解决了诺言,您就应该发送请求.像这样:
Your genToken method should return a Promise and you should send your request once that promise is resolved. Something like:
getToken(...).then((token) => {
res.send(200, token);
}
您可以在此处
这篇关于我在做Promises错误...我在这里想念什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!