获取资源,计算哈希,返回承诺

Posted

技术标签:

【中文标题】获取资源,计算哈希,返回承诺【英文标题】:fetch resource, compute hash, return promise 【发布时间】:2016-02-28 19:50:43 【问题描述】:

我想在浏览器扩展中使用Fetch API 来下载资源并计算其哈希值。以下作品(使用crypto 到Browserify)

fetch(url).then(function(response) 
  return response.blob();
).then(function(data) 
  var a = new FileReader();
  a.readAsBinaryString(data);
  a.onloadend = function() 
    var hash = crypto.createHash(hashType);
    hash.update(a.result, 'binary');
    return hash.digest('hex');
  ;
)

但缺点是我必须等待a.onloadend,而我想嵌入它的上下文需要返回Promise。此外,首先获取整个 blob,然后将其读入 FileReader,然后再将其转储到 createHash,这似乎很奇怪。

有什么提示吗?

【问题讨论】:

也许这个问题更适合codereview.stackexchange.com? 这个问题看起来可能非常适合Code Review.SE,前提是 (a) 您希望审查代码的每个方面,而不仅仅是一些,( b) 您的代码已经在工作,并且 (c) 您要求审查具体的、真实的代码,而不是抽象设计(无论它是否表示为代码)。如果您同意所有这些,请阅读what's on topic,如果您的问题符合,请在此处删除并重新发布到 CR。 (a) 和 (c) 在这里不适用,所以我觉得不合适。 @NicoSchlömer 好的,感谢您的澄清,在这种情况下,Stack Overflow 应该可以正常工作! 我不知道这是针对节点还是网络浏览器? Fetch API 似乎提示 Web 浏览器,crypto.createHash 似乎提示节点(Chrome 在crypto 中似乎没有)...但无论如何,如果这像你说的那样工作,那么看起来你可以只接受 @ 987654334@ 直接来自已解决的承诺并在hash.update 中使用它还是会爆炸? 【参考方案1】:

我认为您在这里要求的是承诺链。您可以在 then 处理程序中创建一个 Promise 并返回它。

var yaypromise = fetch(url).then(function(response) 
  return response.blob();
).then(function(data) 
  return new Promise(function(resolve, reject)
      var a = new FileReader();
      a.readAsBinaryString(data);
      a.onloadend = function() 
        var hash = crypto.createHash(hashType);
        hash.update(a.result, 'binary');
        resolve(hash.digest('hex'));
      ;  
  );
)

然后yaypromise 可能就是您正在寻找的承诺。它将通过hash.digest('hex') 解决

【讨论】:

请只承诺最低级别。将对crypto 的调用放入一个promise 回调中。并且不要忘记附加错误处理程序。【参考方案2】:

crypto hash.update method 也需要一个缓冲区,因此无需通过FileReader 绕道而行。做吧

fetch(url).then(function(response) 
    return response.arrayBuffer();
).then(function(arrayBuffer) 
    var buffer = require('buffer')(new Uint8Array(arrayBuffer));
    var hash = require('crypto').createHash(hashType);
    hash.update(buffer, 'binary');
    return hash.digest('hex');
)

如果不行,你可以easily promisifyFileReader

function getResult(reader) 
    return new Promise(function(resolve, reject) 
        reader.onload = function() 
            resolve(this.result);
        ;
        reader.onerror = reader.onabort = reject;
    );

并像这样使用它:

fetch(url).then(function(response) 
    return response.blob();
).then(function(data) 
    var a = new FileReader();
    a.readAsBinaryString(data);
    return getResult(a);
).then(function(result) 
    var hash = crypto.createHash(hashType);
    hash.update(result, 'binary');
    return hash.digest('hex');
)

【讨论】:

在您的第一个代码块中,为什么第二个 .then() 处理程序中的同步代码即使在第二个 .then() 处理程序中也是如此?为什么不只是在第一个 .then() 处理程序中没有第二个 .then() 处理程序? @jfriend00: arrayBuffer() 返回一个承诺

以上是关于获取资源,计算哈希,返回承诺的主要内容,如果未能解决你的问题,请参考以下文章

获取返回承诺状态:待定

从异步函数返回的承诺中获取价值

离子存储获取返回一个承诺“Bearer [object Promise]”如何返回一个值并将其用作授权令牌?

Javascript - 异步等待和获取 - 返回值,而不是承诺?

赛普拉斯:如何从自定义命令中获取返回值? (柏树承诺)

异步 Javascript - 使用 Fetch 从 Weather.gov 获取数据以更新页面,但返回的承诺不再可用