文档章节

js的异步调用

gznovice
 gznovice
发布于 2015/12/02 14:42
字数 569
阅读 46
收藏 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
粉丝 9
博文 17
码字总数 3853
作品 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
深入理解Node.js:核心思想与源码分析【1】

标签: node 源码 学习 源码: nianniuer node背景,了解一下 (1)体系架构 Node.js主要分为四大部分,Node Standard Library,Node Bindings,V8,Libuv,架构图如下: Node Standard Libra...

张倩1488543336000
07/02
0
0
客户端的js js脚本的引入 js的解析过程

web浏览器中的JavaScript web浏览器中的js通常称为客户端的JavaScript 客户端 JavaScript window对象是所有客户端JavaScript特性和api的主要接入点。 即,表示web浏览器一个窗口或窗体。使用...

小小____
08/03
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Spring Aop原理之切点表达式解析

在前面的文章(Spring AOP切点表达式详解)中,我们总结了Spring Aop切点表达式的用法,而在上文(Spring Aop原理之Advisor过滤)中我们讲到,切点表达式的解析主要是在PatternParser.parse...

爱宝贝丶
16分钟前
0
0
网络工程师真的也需要好好学习linux系统

作为一名刚工作半年的小网工,想总结一下工作半年来的一些感悟。由于本人是网络工程专业,毕业前找工作的目标也是网络工程师,在经过几次面试后如愿以偿的找到了网络工程师的工作。由于上学时...

linuxprobe16
22分钟前
0
0
RabbitMQ在CentOS环境安装

1.废话不多说准备一台虚拟机,系统为centos,我这里使用的系统版本如下图所示:

凌晨一点
59分钟前
0
0
线程池相关

在java.util.concurrent包下,提供了一系列与线程池相关的类。 使用线程池的好处 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗; 提高响应速度。当任务到达时,任务...

edwardGe
今天
0
0
学习大数据这三个关键技术是一定要掌握!

大数据时代全面来临,大数据、人工智能等技术引领科技创新潮流,获得国家政策大力支持,前景广阔。学习大数据技术的人自然是络绎不绝, 学习大数据虽然是一个趋势,但也要注意大数据培训课程...

董黎明
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部