文档章节

js的异步调用

gznovice
 gznovice
发布于 2015/12/02 14:42
字数 569
阅读 51
收藏 0

我在测试用google的CryptoJS库来计算文件的md5和sha1。


最简单的异步调用

var fr = new FileReader;
fr.onload=function(event){
var _bytelength = fr.result.byteLength;
var binary =  CryptoJS.lib.WordArray.create(fr.result);
var md5 = CryptoJS.MD5(binary).toString();
var sha1 = CryptoJS.SHA1(binary);
var base64 = sha1.toString(CryptoJS.enc.Base64);;
    console.log(md5);
document.getElementById("message").innerHTML = "file " + currentFile.name + " is read" + "<p>" + "md5 is " + md5 
+ "<p>" + "sha1 is " + base64;
}
fr.readAsArrayBuffer(_file);

这样是没有问题的。


但是当我计算上百兆的文件的时候,一次性的load文件,浏览器就会崩掉,下面是改进代码,区别是slice文件后,读取每一个blob,计算每一个blog的md5,sha1,当读完所有blob后,就计算出结果来。

function readFile(_file)
{
currentFile =  _file;
var startByte, endByte;
startByte = endByte = 0; 
var fileSize = _file.size;
var md5_cal = CryptoJS.algo.MD5.create();
var sha1_cal = CryptoJS.algo.SHA1.create();
var blob;
var cnt = 0;//rememeber the count of calling of readBlob 
var readBlob = function(_blob)
{
var fr = new FileReader;
fr.onload=function(event){
var binary =  CryptoJS.lib.WordArray.create(fr.result);
md5_cal.update(binary);
sha1_cal.update(binary);
cnt = cnt - 1;
};
/*fr.onloadend=function(event){
if(this.readyState == FileReader.DONE) {  
var binary =  CryptoJS.lib.WordArray.create(fr.result);
md5_cal.update(binary);
sha1_cal.update(binary);
}
};*/
fr.readAsArrayBuffer(_blob);
};
while(endByte != fileSize)
{
endByte = Math.min(startByte + 102400, fileSize);
blob = _file.slice(startByte, endByte);
readBlob(blob);
startByte = endByte;
cnt = cnt + 1;
}
function printResultIfReady()
{
if(cnt == 0)
{
var md5 = md5_cal.finalize().toString();
var sha1 = sha1_cal.finalize();
var base64 = sha1.toString(CryptoJS.enc.Base64);
document.getElementById("message").innerHTML = "file " + currentFile.name + " is read" + "<p>" + "md5 is " + md5 
+ "<p>" + "sha1 is " + base64;
}
else{
setTimeout(printResultIfReady, 500);
}
}
setTimeout(printResultIfReady,500);
}


但由于异步调用的先后完成的顺序不一样,导致各个浏览器的计算结果不同,chrome的正确,ie和firefox错误,但各自不同。

于是我改进下,就是当前一个blob读取调用完成后,才进行下一个blob的读取,这样就没有问题了。

function readFile(_file)
{
currentFile =  _file;

var startByte, endByte;
startByte = endByte = 0; 
var fileSize = _file.size;
var md5_cal = CryptoJS.algo.MD5.create();
var sha1_cal = CryptoJS.algo.SHA1.create();
var blob;
var cnt = 0;//rememeber the count of calling of readBlob 
var _readFile = function()
{
endByte = Math.min(startByte + 102400, fileSize);
blob = _file.slice(startByte, endByte);
readBlob(blob);
startByte = endByte;
cnt = cnt + 1;
}
var readBlob = function(_blob)
{
var fr = new FileReader;
fr.onload=function(event){
var binary =  CryptoJS.lib.WordArray.create(fr.result);
md5_cal.update(binary);
sha1_cal.update(binary);
cnt = cnt - 1;
if(endByte != fileSize)
{
_readFile();
}
else{
printResultIfReady();
}
};

fr.readAsArrayBuffer(_blob);
};

function printResultIfReady()
{
var md5 = md5_cal.finalize().toString();
var sha1 = sha1_cal.finalize();
var base64 = sha1.toString(CryptoJS.enc.Base64);
document.getElementById("message").innerHTML = "file " + currentFile.name + " is read" + "<p>" + "md5 is " + md5 
+ "<p>" + "sha1 is " + base64;
}
if(endByte != fileSize)
{
_readFile();
}
}




代码很丑陋,不过可以说明问题就好。

© 著作权归作者所有

共有 人打赏支持
gznovice
粉丝 12
博文 17
码字总数 3853
作品 0
广州
React Native之js同步调用安卓原生方法@ReactMethod(isBlockingSynchronousMethod = true)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011068702/article/details/82793854 1 问题 之前的代码js调用安卓原生都是用的异步方法,比如callback, pro...

chenyu_insist
09/20
0
0
【iOS & Web】JavaScript & Objective-C二重奏

一、JS call OC 方法1: 通拦截协议头来获取协议字符串。在UIWebView中的代理方法中有这样的方法,如下图所示: 下面是我写的简单的H5页面通过JS请求一个自定义协议的URL,然后通过UIWebView...

魔笛GNR
2016/10/19
0
0
探索Javascript异步编程

笔者在之前的一片博客中简单的讨论了Python和Javascript的异同,其实作为一种编程语言Javascript的异步编程是一个非常值得讨论的有趣话题。 JavaScript 异步编程简介 回调函数和异步执行 所谓...

naughty
2014/05/22
0
8
JSON,异步加载(学习笔记)

JSON是一种传输数据的格式(以对象为样板,本质上就是对象,但用途有区别,对象就是本地用的,json是用来数据传输的,前端与后端的数据通信) JSON是静态类(不需要构造),类似于Math,内部...

Mrs_CoCo
04/23
0
0
Javascript 异步实现机制

Javascript 单线程指的是在一个浏览器进程中只存在一个 Javascript 执行线程,所以任务需要顺序排列等待执行,而不能像 Java 等多线程语言一样并发执行。但是这种单线程模型在处理耗时的异步...

木头先生
2017/12/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

中国移动蔡谦:5G传输准备就绪

目前5G已成业界热议话题,在即将到来的万物互联时代,5G是非常关键的技术。且5G相比4G,业务场景多种多样,对5G承载网带来巨大挑战。5G传输,承载先行并不仅仅是一个口号。当前5G承载网的部署...

linux-tao
22分钟前
4
0
维护“修理权”,苹果使用专有软件工具来修复MacBook Pro和iMac Pro

根据上月发给苹果授权服务提供商的一份文件,苹果公司正在使用新的专有软件诊断工具来修复MacBook Pros和iMac Pros,如果不用专有软件工具来修复关键部件,将会导致“系统失效和修复不完整”...

linuxCool
52分钟前
2
0
cacti监控安装

cacti是用PHP实现的一个软件,它用snmp服务获取数据,然后用rrdtool存储和更新数据,并生成图表展示。比较适合用于交换机、路由器的网络监控,插件众多,可图示化显示网络状况。 cacti官方推...

hiwill
今天
4
0
shell特殊符号、cut、sort、uniq、wc、tee、tr、split命令

10月15日任务 8.10 shell特殊符号cut命令 8.11 sort_wc_uniq命令 8.12 tee_tr_split命令 8.13 shell特殊符号下 cut 命令 cut作用:截取字符串 用法如下:cat /etc/passwd |head -2 |cut -d ...

hhpuppy
今天
4
0
Springboot实现filter拦截token验证和跨域

背景 web验证授权合法的一般分为下面几种 1使用session作为验证合法用户访问的验证方式 使用自己实现的token 使用OCA标准 在使用API接口授权验证时,token是自定义的方式实现起来不需要引入其...

funnymin
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部