简体   繁体   English

打字稿async /等待不起作用

[英]Typescript async/await not working

I've a problem about async/await on typescript with target es2017. 我对目标es2017的打字稿上的async / await有一个问题。 Below is my code : 以下是我的代码:

my route.ts : 我的路线:

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') });

};

my helper.ts : 我的帮手.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;
}

this auth route supposed to return JWT token when user login. 这个auth路由应该在用户登录时返回JWT令牌。 but the problem here is even when I enter the valid password to sign-in the function compareHashPassword always return undefined. 但这里的问题是即使我输入有效密码登录函数compareHashPassword总是返回undefined。

For example when i call the api with json string 例如,当我用json字符串调用api时

{
  "username": "x",
  "password": "helloword"
}

When i track using console.log(), the log is : 当我使用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

maybe this is just my lack of understanding about using async/await with typescript. 也许这只是我对使用ascript / await和typescript缺乏了解。 for note my env is : 注意我的环境是:

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"
    ]
}

In order for async/await to work, an async function has to return a Promise . 为了使async / await工作,异步函数必须返回一个Promise Also, you must call an async with the await keyword this way: 此外,您必须以这种方式使用await关键字调用async

You can only call await inside an async function, so I wrapped it in an async func 你只能在异步函数中调用await,所以我把它包装在异步函数中

const someFunc = async function() {
    return new Promise((resolve, reject) => { 
        setTimeout(resolve, 100, true);
    });
};

(async () => {
     const result = await someFunc(); // true
})();

You are not satisfying any of these rules in your compareHashPassword declaration and the way you call it. 您在compareHashPassword声明中以及调用它时的方式不满足任何这些规则。

This is how I would rewrite your code : 这就是我重写代码的方式:

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);
})()

Have a look at this async await blog post: https://ponyfoo.com/articles/understanding-javascript-async-await 看看这个异步等待博客文章: https//ponyfoo.com/articles/understanding-javascript-async-await

And this blog post for Promises: https://developers.google.com/web/fundamentals/primers/promises 这篇关于Promises的博客文章: https//developers.google.com/web/fundamentals/primers/promises

Also as @Patrick Roberts mentioned, you can use util.promisify to turn an async callback style function into a Promise, this is node 8.xx otherwise you can use bluebird package which has a similar functionality. 同样正如@Patrick Roberts所提到的,你可以使用util.promisify将异步回调样式函数转换为Promise,这是node 8.xx否则你可以使用具有类似功能的bluebird包。

Hope this helps 希望这可以帮助

Since you're targeting ES2017, let's clean up your code, starting with the simpler helper.ts : 既然你的目标是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);
}

Now for the route.ts : 现在为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')
  }
}

Hopefully I've matched what you're attempting to accomplish, based on the code you've provided. 希望我根据您提供的代码与您尝试完成的内容相匹配。 If there's an issue somewhere with this updated code, please let me know in the comments. 如果这个更新的代码出现问题,请在评论中告诉我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM