[英]Typescript async/await not working
我對目標es2017的打字稿上的async / await有一個問題。 以下是我的代碼:
我的路線:
method: 'POST',
config: {
auth: {
strategy: 'token',
}
},
path: '/users',
handler: (request, reply) {
let { username, password } = request.payload;
const getOperation = User
.findAll({
where: {
username: username
}
})
.then(([User]) => {
if(!User) {
reply({
error: true,
errMessage: 'The specified user was not found'
});
return;
}
let comparedPassword = compareHashPassword(User.password, password);
console.log(comparedPassword);
if(comparedPassword) {
const token = jwt.sign({
username,
scope: User.id
}, 'iJiYpmaVwXMp8PpzPkWqc9ShQ5UhyEfy', {
algorithm: 'HS256',
expiresIn: '1h'
});
reply({
token,
scope: User.id
});
} else {
reply('incorrect password');
}
} )
.catch(error => { reply('server-side error') });
};
我的幫手.ts:
export async function compareHashPassword(pw:string, originalPw:string) {
console.log(pw);
console.log(originalPw);
let compared = bcrypt.compare(originalPw, pw, function(err, isMatch) {
if(err) {
return console.error(err);
}
console.log(isMatch);
return isMatch;
});
return await compared;
}
這個auth路由應該在用戶登錄時返回JWT令牌。 但這里的問題是即使我輸入有效密碼登錄函數compareHashPassword總是返回undefined。
例如,當我用json字符串調用api時
{
"username": "x",
"password": "helloword"
}
當我使用console.log()跟蹤時,日志是:
$2a$10$Y9wkjblablabla -> hashed password stored in db
helloword
Promise {
<pending>,
domain:
Domain {
domain: null,
_events: { error: [Function: bound ] },
_eventsCount: 1,
_maxListeners: undefined,
members: [] } }
true
也許這只是我對使用ascript / await和typescript缺乏了解。 注意我的環境是:
node : v8.6.0
typescript : v2.5.2
ts-node : v3.3.0
my tsconfig.json //
{
"compilerOptions": {
"outDir": "dist",
"target": "es2017",
"module": "commonjs",
"removeComments": true,
"types": [
"node"
],
"allowJs": true,
"moduleResolution": "classic"
},
"exclude": [
"node_modules"
]
}
為了使async / await工作,異步函數必須返回一個Promise
。 此外,您必須以這種方式使用await關鍵字調用async
:
你只能在異步函數中調用await,所以我把它包裝在異步函數中
const someFunc = async function() {
return new Promise((resolve, reject) => {
setTimeout(resolve, 100, true);
});
};
(async () => {
const result = await someFunc(); // true
})();
您在compareHashPassword
聲明中以及調用它時的方式不滿足任何這些規則。
這就是我重寫代碼的方式:
export async function compareHashPassword(pw:string, originalPw:string) {
return new Promise((resolve, reject) => {
bcrypt.compare(originalPw, pw, function(err, isMatch) {
if(err) {
reject(err);
}
console.log(isMatch);
resolve(isMatch);
});
});
}
// and call it this way
(async () => {
const compared = await compareHashPassword(pw, originPw);
})()
看看這個異步等待博客文章: https : //ponyfoo.com/articles/understanding-javascript-async-await
這篇關於Promises的博客文章: https : //developers.google.com/web/fundamentals/primers/promises
同樣正如@Patrick Roberts所提到的,你可以使用util.promisify
將異步回調樣式函數轉換為Promise,這是node 8.xx
否則你可以使用具有類似功能的bluebird
包。
希望這可以幫助
既然你的目標是ES2017,那么讓我們從簡單的helper.ts
開始清理你的代碼:
import { promisify } from 'util' // you'll thank me later
const compare = promisify(bcrypt.compare)
export async function compareHashPassword(pw:string, originalPw:string) {
console.log(pw);
console.log(originalPw);
return compare(originalPw, pw);
}
現在為route.ts
:
handler: async (request, reply) => {
let { username, password } = request.payload;
try {
const [user] = await User.findAll({
where: {
username: username
}
})
if(!user) {
reply({
error: true,
errMessage: 'The specified user was not found'
});
return;
}
let match = await compareHashPassword(user.password, password);
console.log(match);
if (match) {
const token = jwt.sign({
username,
scope: User.id
}, 'iJiYpmaVwXMp8PpzPkWqc9ShQ5UhyEfy', {
algorithm: 'HS256',
expiresIn: '1h'
});
reply({
token,
scope: user.id
});
} else {
reply('incorrect password');
}
} catch (error) {
reply('server-side error')
}
}
希望我根據您提供的代碼與您嘗試完成的內容相匹配。 如果這個更新的代碼出現問題,請在評論中告訴我。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.