0

我正在编写一个函数来使用 crypto.randomBytes 生成一个随机密钥,它需要一个回调。我更喜欢使用异步等待,所以我尝试使用 util.promisify 来包装随机字节,如下所示:

const crypto = require('crypto');
const util = require('util');

const randBytes = util.promisify(crypto.randomBytes);

async function genRandKey() {

  bytes = await randBytes(48).catch((err) => {
    console.log(err);
  });

  return bytes.toString('hex');
}

let result = genRandKey();
console.log('key: ', result);

但这会打印key: Promise { <pending> }而不是打印解析的值。我在这里做错了什么?

4

2 回答 2

2

所有async函数都返回一个promise。所以你的genRandKey()函数也返回一个promise。您必须使用awaitor.then()的结果来自genRandKey(). 仅仅因为您转换为 promise 并使用await并不意味着您可以直接从函数返回值。这不是函数中发生的事情async。函数中的returnasync只是函数返回的承诺的解析值。虽然代码看起来像您直接返回值,但实际情况并非如此。

在 Javascript/node.js 中,没有办法获取异步检索的值并直接从函数中返回它。它必须通过承诺、回调或事件来传达。没有其他办法了。


现在,在这种特定情况下,有一个同步版本,crypto.randomBytes()您可以使用它来代替。异步版本的存在是有原因的,因为crypto.randomBytes()运行需要一点时间,如果你使用同步版本,它会在运行时阻塞事件循环。取决于您正在做什么,这可能是也可能不是问题。异步版本crypto.randomBytes()在单独的线程中运行实际的加密操作(使用 libuv 线程池)并异步返回值,因此它不会阻塞事件循环。

于 2020-04-30T16:59:00.533 回答
1

async 函数genRandKey()被同步调用,所以它会返回一个Promise. 功能完成后,您可以使用该.then()功能写入控制台。您需要更改以下代码:

let result = genRandKey();
console.log('key: ', result);

genRandKey().then((result) => {
    console.log('key: ', result);
});

但是,这将导致在其余代码运行时异步调用该函数。一个解决方案可能是将整个程序包装在一个自动执行的异步函数中并使用await关键字:

(async () => {
    const crypto = require('crypto');
    const util = require('util');

    const randBytes = util.promisify(crypto.randomBytes);

    async function genRandKey() {
        bytes = await randBytes(48).catch((err) => {
            console.log(err);
        });

        return bytes.toString('hex');
    }

    let result = await genRandKey();
    console.log('key: ', result);
})();

或者,您可以将其余代码放入.then()函数中:

const crypto = require('crypto');
const util = require('util');

const randBytes = util.promisify(crypto.randomBytes);

async function genRandKey() {
    bytes = await randBytes(48).catch((err) => {
        console.log(err);
    });

    return bytes.toString('hex');
}

genRandKey().then((result) => {
    console.log('key: ', result);

    ...rest of code...
});
于 2020-04-30T17:15:35.850 回答