我在做Promises错误...我在这里想念什么? [英] I'm doing Promises wrong... What am I missing here?

查看:75
本文介绍了我在做Promises错误...我在这里想念什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个文件 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆