首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Typescript async/await不工作

Typescript async/await不工作
EN

Stack Overflow用户
提问于 2017-09-27 17:50:42
回答 2查看 12.2K关注 0票数 8

我有一个关于异步/等待与目标es2017的typescript的问题。下面是我的代码:

我的route.ts:

代码语言:javascript
复制
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') });

};

我的helper.ts:

代码语言:javascript
复制
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;
}

此身份验证路由应在用户登录时返回JWT令牌。但这里的问题是,即使我输入有效的密码进行登录,函数compareHashPassword也总是返回undefined。

例如,当我使用json string调用api时

代码语言:javascript
复制
{
  "username": "x",
  "password": "helloword"
}

当我使用console.log()跟踪时,日志是:

代码语言:javascript
复制
$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

也许这只是我对在typescript中使用async/await的理解不足。注意,我的env是:

代码语言:javascript
复制
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"
    ]
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-09-27 18:02:58

为了使异步/等待工作,异步函数必须返回一个Promise。此外,您必须以这种方式调用带有await关键字的async

await您只能在异步函数内部调用,所以我将其包装在异步函数

代码语言:javascript
复制
const someFunc = async function() {
    return new Promise((resolve, reject) => { 
        setTimeout(resolve, 100, true);
    });
};

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

您在compareHashPassword声明和调用方式中没有满足这些规则中的任何一条。

这就是我如何重写你的代码:

代码语言:javascript
复制
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);
})()

看看这篇async await博客文章: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包。

希望这能有所帮助

票数 12
EN

Stack Overflow用户

发布于 2017-09-27 18:34:28

由于您的目标是ES2017,因此让我们从更简单的helper.ts开始清理代码

代码语言:javascript
复制
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

代码语言:javascript
复制
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')
  }
}

希望根据您提供的代码,我已经匹配了您试图实现的目标。如果这个更新的代码有什么问题,请在评论中告诉我。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46444745

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档