Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript I';我做错了承诺。。。我错过了什么?_Typescript_Promise_Jwt_Aurelia_Es6 Promise - Fatal编程技术网

Typescript I';我做错了承诺。。。我错过了什么?

Typescript I';我做错了承诺。。。我错过了什么?,typescript,promise,jwt,aurelia,es6-promise,Typescript,Promise,Jwt,Aurelia,Es6 Promise,我有一个文件token.ts,它导出1个函数: 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 };

我有一个文件token.ts,它导出1个函数:

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函数:

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(用户名、密码)函数并返回token对象

出于某种原因,我不知道为什么,当我第一次提交表单时,“token”(login.ts)没有定义。如果我再次提交表单,那么令牌对象将按预期返回并记录到控制台

有人知道为什么会这样吗?如果我没有包括足够的信息,请让我知道你可能需要什么,这样我可以更新后!谢谢

编辑

根据接受答案中提供的信息,我提出了以下改变,解决了我最初的问题:

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;
};
...
    genToken(username, password)
        .then(token => {
            res.status(200).send(token);
        })
        .catch(err => {
            res.status(500).send(err);
        });

});
login.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;
};
...
    genToken(username, password)
        .then(token => {
            res.status(200).send(token);
        })
        .catch(err => {
            res.status(500).send(err);
        });

});

据我所见,您遇到的问题是,当您尝试以同步方式读取令牌时,令牌是以异步方式生成的

你的genToken方法应该返回一个承诺,一旦这个承诺得到解决,你应该发送你的请求。比如:

getToken(...).then((token) => {
    res.send(200, token);
}

您可以找到一些示例

您确定链接本身没有问题吗?当我第一次执行该函数时,它似乎直接跳到前面的.then语句中定义this.token之前的“returnthis.token”。我已经尝试实现youre方法,但没有任何运气。是的,它“跳转”到返回this.token行,因为db.open()调用是异步的,这意味着调用的结果将在将来某个时候得到解决。在此期间,代码的其余部分将同步执行。看一看,它可能会让我们对承诺有更多的了解。如果你以后仍然卡在那里,请告诉我。谢谢你提供的更多信息。我有一些有用的东西,有点。。。这个概念仍然有点模糊,但它越来越清晰了!我还想问一些其他问题,但我想我需要为此发布一个新问题….?这是一个新问题: