Node.js中如何用async/await改写crypto.randomBytes与createHash代码
错误原因说明
- promisify的作用是将「回调风格的函数」转换为返回Promise的函数,之前直接传入
crypto.randomBytes(32)的执行结果(Buffer实例),不符合参数要求,因此抛出类型错误。 crypto.createHash、update、digest本身是同步计算API,没有异步回调版本,无需使用promisify包装。- 后续输出
[object Promise]是因为没有使用await等待Promise执行完成,直接将Promise对象转为字符串导致。
可正常运行的改写代码
首先提前转换randomBytes为Promise版本:
const { promisify } = require('util'); const crypto = require('crypto'); // 只需要包装randomBytes函数本身,不是执行结果 const randomBytesAsync = promisify(crypto.randomBytes);
改写后的实例方法:
userSchema.methods.createPasswordResetToken = async function() { // 等待异步生成随机字节,再转hex const resetToken = (await randomBytesAsync(32)).toString('hex'); // 哈希计算为同步API,和原写法保持一致即可 this.password_reset_token = crypto.createHash('sha256').update(resetToken).digest('hex'); this.password_reset_expires = Date.now() + (10 * 60 * 1000); console.log({resetToken}, this.password_reset_token); return resetToken; };
注意:调用这个async方法时,必须使用await或者.then()的方式接收返回值,否则只能拿到Promise对象。
同步写法的性能影响
- 原始的同步写法对于生成32字节随机数、做一次sha256哈希的场景,单次执行耗时只有几微秒,几乎不会产生可感知的性能损耗,普通中小流量的服务可以直接保留原写法。
- 如果你的服务QPS极高(每秒数千次以上调用该接口),同步操作的阻塞时间累加会影响Node.js主事件循环的响应,此时使用异步版本的
randomBytes更优,因为异步实现会放到libuv线程池执行,不会阻塞主逻辑。
内容的提问来源于stack exchange,提问作者user10033434
相关产品推荐
相关产品推荐

