2
我有一個文件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(用戶名,密碼)函數並返回標記Object。
出於某種原因,不知道爲什麼,當我第一次提交表單時,「token」(login.ts)未定義。如果我再次提交表單,那麼標記Object將返回並按預期的方式記錄到控制檯。
任何人都知道這可能是爲什麼?如果我沒有收錄足夠的信息,請告訴我您可能需要什麼,以便我可以更新帖子!謝謝!
編輯
基於對接受的答案提供的信息,我想出了已經解決了我最初的問題,以下變化:
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);
});
});
你確定這不是有毛病chainging本身?當我第一次執行函數時,它似乎直接跳到「返回this.token」之前this.token被定義在前面的.then語句中。我嘗試過實施你的方法,但沒有任何運氣。 –
是的,它跳轉到返回this.token行,因爲你的db.open()調用是異步的,這意味着調用的結果將在未來的某個時刻被解決。在此期間,其餘代碼將同步執行。看看https://scotch.io/tutorials/javascript-promises-for-dummies和https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise,它可能會流失更多承諾之光。讓我知道你是否仍然卡住。 – Fjut
感謝您的額外信息。我有一些工作,有點......這個概念仍然有點模糊,但它變得更清晰了!我還有其他的東西出現了,但我想我需要爲此發佈一個新問題..? –