fetch resource, compute hash, return promise

折月煮酒 提交于 2019-12-23 09:56:46

问题


I would like to use the 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');
  };
})

but has the disadvantage that I have to wait for a.onloadend while the context in which I'd like to embed it requires a Promise to be returned. Also, it seems quite weird to first fetch the entire blob, then read it into a FileReader just to dump it into createHash afterwards.

Any hints?


回答1:


The crypto hash.update method also takes a buffer, so there is no need to make a detour via a FileReader. Just do

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

If that doesn't work, you can easily promisify a FileReader:

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

and use it like this:

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



回答2:


I think what you're asking for here is promise chaining. You can create a promise inside the then handler and return it.

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

And then yaypromise is probably the promise you're looking for. It will resolve with hash.digest('hex')



来源:https://stackoverflow.com/questions/33926399/fetch-resource-compute-hash-return-promise

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!