【问题标题】:How do I await a callback inside a function call in node?如何在节点中的函数调用中等待回调?
【发布时间】:2020-08-12 21:53:57
【问题描述】:

好的,所以我正在尝试使用加密 (https://nodejs.org/api/crypto.html#crypto_crypto_generatekeypair_type_options_callback) 生成公钥和私钥

问题是,generateKeyPair 的参数之一是回调函数,我无法让我的代码等待回调运行。它最终会运行,但到那时我已经尝试使用这些数据。我们的想法是做这样的事情:

const _getKeyPair = (pwd: string): Object => {
    const { generateKeyPair }: any = require('crypto');

    const keyPair = { publicKey: '', privateKey: '' };
    generateKeyPair('rsa', {
        modulusLength: 4096,
        publicKeyEncoding: {
            type: 'spki',
            format: 'pem'
        },
        privateKeyEncoding: {
            type: 'pkcs8',
            format: 'pem',
            cipher: 'aes-256-cbc',
            passphrase: pwd
        }
    }, (err: Error, publicKey: string, privateKey: string) => {
        if (err) {
            throw err;
        }
        keyPair.publicKey = publicKey;
        keyPair.privateKey = privateKey;
    });

    return keyPair;
};

然后调用:

const keyPair = _getKeyPair('myPassword');

【问题讨论】:

  • 因此,通过回调异步检索值的 Javascript 函数根本无法从函数中返回该值。正如您已经看到的,函数在调用回调之前返回,因此该值不知道函数何时返回。用于反馈异步值的选项是回调、承诺或事件。详情在这里How do I return the response from an asynchronous call
  • 在返回之前,您不会在 Javascript 中“等待回调”。即使您转向所有承诺并使用async/await,该函数仍会在您的第一个await 处返回一个承诺,这只是延迟的承诺的解决,调用者必须使用带有@ 的承诺987654327@或.then()获取值。

标签: node.js typescript async-await


【解决方案1】:

crypto 有两种生成密钥对的方法,一种是异步的generateKeyPair,另一种是同步的generateKeyPairSync,如果你想要的话,你可以使用它们而不必担心回调。另一种方法是用 promise 包装方法并使用await。比如:

const _getKeyPair = async (pwd) => {
  const { generateKeyPair } = require('crypto');

  return new Promise((resolve, reject) => {
    generateKeyPair('rsa', {
      modulusLength: 4096,
      publicKeyEncoding: {
        type: 'spki',
        format: 'pem'
      },
      privateKeyEncoding: {
        type: 'pkcs8',
        format: 'pem',
        cipher: 'aes-256-cbc',
        passphrase: pwd
      }
    }, (err, publicKey, privateKey) => {
      if (err) return reject(err);
      resolve({publicKey, privateKey});
    });
  });
};

async function main() {
  const keyPair = await _getKeyPair('myPassword');
}

main();

【讨论】:

  • 应该注意crypto 模块提供异步(基于回调)操作的原因是因为某些加密操作是 CPU 密集型的,并且可能会在不希望的时间内阻塞事件循环。当您使用异步版本时,它会将加密操作传递给线程池,并在不阻塞事件循环的情况下执行 CPU 密集型工作。因此,直接跳到同步方法并不总是最好的选择。
猜你喜欢
  • 2021-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-28
  • 1970-01-01
  • 2017-09-03
  • 2019-09-19
相关资源
最近更新 更多