gpt4 book ai didi

node.js - 通过静态函数的异步构造函数,但await不起作用

转载 作者:太空宇宙 更新时间:2023-11-03 22:08:19 25 4
gpt4 key购买 nike

我创建了一个简单的用户类,其中包含用户名、散列密码和密码盐。因为哈希和加盐需要一些时间,所以我决定创建一个静态异步函数来创建一个新用户( Asynchronous constructor )。但不知何故,当我调用这个静态异步函数来创建新用户时,等待不会等待 createUser 完成。有谁知道为什么吗?

  console.log(1);
var newUser = await User.createUser(newUserJson);
console.log(3);
console.log(newUser.getPasswordHash()); //<- this line fails with the error that it cannot do the .getPasswordHash on undefined.


static async createUser(jsonUser) {
var password = jsonUser.password;
const saltRounds = 10;
try {
bcrypt.genSalt(saltRounds, function(err, salt) {
bcrypt.hash(password, salt, function(err, hash) {
jsonUser.passwordHash = hash;
jsonUser.passwordSalt = salt;

var us = new User(jsonUser); //nonblocking. Just sets some fields.
console.log(2);
return us;
});
})
} catch (err) {
console.log('error')
console.log(err)
}
}

我的控制台输出显示 1, 3, 2...

有人知道为什么 newUser.getPasswordHash() 不等待 var newUser = wait User.createUser(newUserJson); ?

最佳答案

这几乎概括了 async/await 上的困惑。 。你似乎认为你需要做一些像 async 的东西为了await它。它实际上是相反,因为您标记为 async为了“包含”您想要的方法 await 。如前所述,您需要 bcrypt.genSaltbcrypt.hash两者都被包裹在 Promise 中.

有一些库可以做到这一点,或者您可以使用已经包含的“vanilla”函数来滚动它。当然,您也会在错误的位置捕获异常:

static createUser(jsonUser) {
const { password } = jsonUser;
const saltRounds = 10;

return new Promise((resolve,reject) =>
bcrypt.genSalt(saltRounds, (err, salt) => {
if (err) reject(err);
resolve(salt);
})
).then(salt => new Promise((resolve,reject) =>
bcrypt.hash(password, salt, (err, hash) => {
if (err) reject(err);

jsonUser.passwordHash = hash;
jsonUser.passwordSalt = salt;

var us = new User(jsonUser);
resolve(us);
})
);
}

或者,如果您“真的想要”使用 await而不是用 .then() 链接 promise ,那就是你用 async 标记的时候:

static async createUser(jsonUser) {                  // marked as async
const { password } = jsonUser;
const saltRounds = 10;

let salt = await new Promise((resolve,reject) => // because we await here
bcrypt.genSalt(saltRounds, (err, salt) => {
if (err) reject(err);
resolve(salt);
})
);

return new Promise((resolve,reject) =>
bcrypt.hash(password, salt, (err, hash) => {
if (err) reject(err);

jsonUser.passwordHash = hash;
jsonUser.passwordSalt = salt;

var us = new User(jsonUser);
resolve(us);
})
);
}

所以它只是定义一个返回 Promise 的函数,没有什么比这更神奇的了。

然后当然你实际上使用你的 await获取标记为 async 的 block “内”的值,当然也可以在那里进行异常处理。在这里使用 IIFE 进行演示:

(async function() {  // async marks the block

try {
console.log(1);
var newUser = await User.createUser(newUserJson); // where you can await
console.log(3);
console.log(newUser.getPasswordHash()); // This is expected to be NOT async
} catch(e) {
console.error(e);
}

})()

所以这里根本没有什么神奇的,而 async/await简单来说就是“糖”,用于调用 .then()获取 Promise 的解析值。但函数本身只是 Promise返回,您只需标记为 async其中代码的“内部 block ”实际上调用 await .

按照这个就可以了,当然如果 User.getPasswordHash()实际上是一个“异步”函数本身,那么你同样想返回 Promise从那开始,然后 await结果:

 console.log(await newUser.getPasswordHash());

但是如果 new User()不是异步的,那么您可能没有异步子方法。

关于node.js - 通过静态函数的异步构造函数,但await不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49829713/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com