簡體   English   中英

打字稿async /等待不起作用

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM