获取资源,计算哈希,return promise

fetch resource, compute hash, return promise

我想使用 Fetch API in a browser extension to download a resource and compute a hash thereof. The following works (using crypto through 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 中似乎很奇怪。

有什么提示吗?

我认为您在这里要求的是承诺链接。您可以在 then 处理程序和 return 内部创建一个承诺。

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 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 promisify a FileReader:

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');
})