2015-11-25 17 views
5

Tôi muốn sử dụng Fetch API trong tiện ích mở rộng trình duyệt để tải xuống tài nguyên và tính toán băm của tài nguyên đó. Các công trình sau đây (sử dụng crypto qua Browserify)tìm nạp tài nguyên, băm tính toán, lời hứa trả lại

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

nhưng có những bất lợi mà tôi phải chờ a.onloadend trong khi bối cảnh trong đó tôi muốn nhúng nó đòi hỏi một Promise để được trả lại. Ngoài ra, có vẻ như khá lạ khi lần đầu tiên tìm nạp toàn bộ đốm màu, sau đó đọc nó vào một số FileReader chỉ để đổ nó vào createHash sau đó.

Bất kỳ gợi ý?

+0

Có lẽ câu hỏi này tốt hơn sẽ phù hợp cho http: //codereview.stackexchange.com? – Pavlo

+0

Câu hỏi này có vẻ phù hợp với [Code Review.SE] (http://codereview.stackexchange.com/), với điều kiện (a) bạn muốn _every aspect_ của mã được xem xét, không chỉ một số, (b) mã của bạn là _already working_, và (c) bạn đang yêu cầu xem xét _concrete, code_ thực, không phải là thiết kế trừu tượng (có hay không nó được thể hiện dưới dạng mã). Nếu bạn đồng ý với tất cả những điều đó, vui lòng đọc về [chủ đề gì] (http://codereview.stackexchange.com/help/on-topic), và nếu câu hỏi của bạn phù hợp với điều đó, hãy xóa nó ở đây và đăng lại nó trên CR . – Phrancis

+0

(a) và (c) không áp dụng ở đây, vì vậy tôi đoán nó không phù hợp. –

Trả lời

2

crypto hash.update method cũng có bộ đệm, vì vậy không cần phải đi vòng qua FileReader. Chỉ cần làm

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

Nếu điều đó không làm việc, bạn có thể easily promisify một FileReader:

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

và sử dụng nó như thế này:

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

Trong khối mã đầu tiên của bạn tại sao mã đồng bộ trong trình xử lý '.then()' thứ hai ngay cả trong một trình xử lý '.then()' thứ hai? Tại sao nó không phải chỉ trong trình xử lý '.then()' đầu tiên mà không có trình xử lý '.then()' thứ hai? – jfriend00

+0

@ jfriend00: 'arrayBuffer()' trả về một lời hứa – Bergi

+0

Khối đầu tiên thực hiện công việc. Cảm ơn rất nhiều! –

2

Tôi nghĩ rằng những gì bạn đang yêu cầu ở đây là hứa hẹn chuỗi. Bạn có thể tạo lời hứa bên trong trình xử lý then và trả lại lời hứa đó.

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

Và sau đó yaypromise có lẽ là lời hứa bạn đang tìm kiếm. Nó sẽ giải quyết với hash.digest('hex')

+0

Vui lòng chỉ promisify ở mức thấp nhất.Đặt cuộc gọi đến 'crypto' trong lời gọi lại lời hứa. Và đừng quên đính kèm một trình xử lý lỗi. – Bergi

Các vấn đề liên quan