【问题标题】:How do I synchronise crypto.randomBytes() function of crypto module in node js?如何在节点 js 中同步加密模块的 crypto.randomBytes() 函数?
【发布时间】:2020-07-17 08:37:47
【问题描述】:
crypto = require('crypto')
async function generateToken(){
  await crypto.randomBytes(256,function(ex, buffer) {
    if (ex) {
      console.log("error generating token");
    }

        var token =  crypto
          .createHash('sha1')
          .update(buffer)
          .digest('hex');

        console.log(token);



  }
)}
console.log("before token");
generateToken();
console.log("after token");

在上面的代码中,我想同步generateToken()方法。所以我在函数中添加了asyncawait,但我没有得到预期的输出

before token 
7f4f27037cd7dd65bd03d7e2fe859e608b9eebe2
after token 

我得到的输出是

before token 
after token
7f4f27037cd7dd65bd03d7e2fe859e608b9eebe2

我在上面的代码中做错了什么?

编辑: 以下代码可以工作,但不同步。

crypto = require("crypto");
function generateToken() {
  return new Promise((resolve, reject) => {
    crypto.randomBytes(256, function(ex, buffer) {
      if (ex) {
        reject("error generating token");
      }
      const token = crypto
        .createHash("sha1")
        .update(buffer)
        .digest("hex");
      resolve(token);
    });
  });


  console.log(token);
}

console.log("before token");
generateToken().then((token) => {
  console.log(token);
  console.log("after token");
});

【问题讨论】:

  • 下面的答案总结了它,当您调用 generateToken() 时,它不会阻塞,因此控制台日志语句完全符合您的预期。

标签: node.js async-await


【解决方案1】:
const crypto = require("crypto");
async function generateToken() {
  const buffer = await new Promise((resolve, reject) => {
    crypto.randomBytes(256, function(ex, buffer) {
      if (ex) {
        reject("error generating token");
      }
      resolve(buffer);
    });
  });
  const token = crypto
    .createHash("sha1")
    .update(buffer)
    .digest("hex");

  console.log(token);
  return token;
}

console.log("before token");
generateToken().then(token => {
  console.log("after token", token);
});

你也可以在其他异步函数中调用它

async function otherFunction() {
  try {
    console.log("before token");
    const token = await generateToken();
    console.log("after token", token);
  } catch (e) {
    console.error(e)
  }
}

【讨论】:

  • 我不认为 generateToken 方法是同步的。我不想在这里使用 then 函数。
  • 你想在哪里使用它?
  • 我希望能够写出这样的东西 console.log("before token");生成令牌(); console.log("令牌后");
  • 您可以在其他异步函数中使用 await 执行此操作,然后您可以调用其他函数
【解决方案2】:

如果您不指定函数,则使用该函数的同步版本并返回结果字节。

token = crypto.randomBytes(256)

这样你就不需要任何类型的同步(一切都是回调,即使被称为承诺、等待、异步等等......所以异步世界中的同步代码需要每个前面回调以启动下一个异步作业,这在像这样的一些简单情况下可能很烦人。)

【讨论】:

    【解决方案3】:

    一切正常...

     crypto = require("crypto");
    
        function generateToken() {
          return new Promise((resolve, reject) => {
            crypto.randomBytes(256, function(ex, buffer) {
              if (ex) {
                reject();
              }
              const token = crypto
                .createHash("sha1")
                .update(buffer)
                .digest("hex");
              console.log(token);
              resolve();
            });
          });
    
        }
    
        async function otherFunction() {
          try {
            console.log("before token");
            await generateToken()
            console.log("after token");
          } catch (e) {
            console.error(e)
          }
        }
        otherFunction();
    

    【讨论】:

      【解决方案4】:

      以下方法适用于 TypeScript "typescript": "^3.4.4"

      const randomKey = async (length: Number) => {
        const buffer = await crypto.randomBytes(16);
        return buffer.toString("hex");
      };
      
      const getAndLogKey = async () => {
        const randomKey = await randomKey(16);
        console.log(randomKey);
      };
      

      也应该与 JS 一起工作

      【讨论】:

      • 请记住,此代码实际上将使用同步版本的 crypto.randomBytes。在此示例中,可以只删除 async 和 await 关键字。要使用异步版本,您需要包含一个回调作为第二个参数。 (Documentation)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-03
      • 2019-12-23
      • 1970-01-01
      • 2018-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多