为了账号安全,请及时绑定邮箱和手机立即绑定

JS事件循环问题

JS事件循环问题

人到中年有点甜 2019-05-21 10:09:50
我的需求:我的需求可以简单描述为,对一个大文件进行分片切割上传。我实现的思路为,对一个大文件,按照设定的chunksSize切分为N=file.size/chunkSize块,然后循环创建N个读流读取每个分片的内容,然后发起N个http.request的Post请求去上传文件。代码如下(说明:upload函数用来根据分块的个数n,计算每块起始标志位和终止标识位,并调用senddataPromise函数对每片进行操作)functionupload(username,filepath,file_id,filelength,n,alreadychunks,chunkSize){returnnewPromise(function(resolve,reject){varstart=0,end=0;varpromiseall=[];for(letcurindex=0;curindex{console.log(values);console.log("alldone");resolve(true)}).catch(err=>{console.log(err);reject(err);})}},500)})}senddataPromise函数是对第i块分片创建读流读取内容,并调用doapost函数发送到后端functionsenddataPromise(path,options,username,summary,curindex,length){returnnewPromise(function(resolve,reject){letreadSteam=fs.createReadStream(path,options);readSteam.on("data",(chunk)=>{console.log("第"+curindex+"块JSON开始")letchunkjson=JSON.stringify(chunk);console.log("第"+curindex+"块JSON结束")lettempcell={data:chunkjson,n:curindex,file_id:summary,username:username,length:length};chunk=null;chunkjson=null;doapost(tempcell).then(values=>{resolve(values)}).catch(err=>{reject(err);});})})}doapost函数发起post请求发送分片数据functiondoapost(data){returnnewPromise(function(resolve,reject){leti=data.n;console.log("第"+i+"份请求准备发出")letcontents=queryString.stringify(data);data=null;letoptions={host:"localhost",path:"/nodepost/",port:8000,method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded','Content-Length':contents.length}};letreq=http.request(options,function(res){console.log("第"+i+"份请求返回数据")res.on("data",function(chunk){console.log(chunk.toString());});res.on("end",function(d){resolve("end");});res.on("error",function(e){reject(e);})});req.write(contents);req.end();contents=null;console.log("第"+i+"份请求已发出")})}我的问题:按照正常的思路,因为读取文件内容为异步操作,后面发送请求也为异步操作,所以也就是说会出现对于n个分片,读取数据已经读取了p片,并且已经有q(**q
查看完整描述

2 回答

?
噜噜哒

TA贡献1784条经验 获得超7个赞

不是呀,这个是正常的呀,你看第1份post已经发出是在第2块JSON开始之前呀,post发出和http.requset并列,JSON开始是读完文件之后,所以发送数据是在文件读完之前,只是读后面块的时候前面的请求还没有执行完,所以并没有第n份数据返回。网络延时比读取文件大的多,所以文件读完之前不会返回呀。
感觉,这段代码不至于在12的时候内存溢出呀。
nodejs上传文件的话用管道更好一点儿吧。
                            
查看完整回答
反对 回复 2019-05-21
  • 2 回答
  • 0 关注
  • 335 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号