当前位置: 首页 > Web前端 > HTML

分段上传方案

时间:2023-03-28 16:31:04 HTML

1.来自“../tools/emmitter”的index.tsimportEmbitter;importSlicefrom"./sliceUpload";//上传状态conststatusMap={fail:0,//failsuccess:1,//succeedinProcessing:2,//inprogresspaused:3,//pausedcancelled:4,//取消wait:5//未启动};interfaceIConfig{file:File;并行:数字;partSize:number;}classClientextendsEmbitter{私有文件:文件;私人并行:数字;//并行片段数privatepartSize:number;//片段大小privatestatus:number;//0失败1成功2进行中3暂停4取消5未开始6错误privatepartInfo:IPartInfo;私处数组:Slice[];//维护所有切片privatesliceUploadSuccess:Set;//上传成功切片的PartIndexprivatesliceUploadRunning:Set;//上传切片的PartIndexprivatesliceEvent:Embitter;构造函数(配置:IConfig){超级();this.file=配置文件;this.parallel=config.parallel||默认并行;this.partInfo={partSize:config.partSize,partNum:Math.ceil(config.file.size/config.partSize),};this.status=statusMap.wait;//默认不启动this.partsArray=[];//记录切片上传成功this.sliceUploadSuccess=newSet([]);//记录正在上传的Slicethis.sliceUploadRunning=newSet([]);//监听切片上传this.sliceEvent=newEmbitter();}getConfig(){return{file:this.file,partInfo:this.partInfo,sliceEvent:this.sliceEvent,status:this.status,};}privatestartUploadAllSlice(){this.sliceEvent.on("success",(partIndex:number)=>{if(!this.sliceUploadSuccess.has(partIndex)){this.sliceUploadSuccess.add(partIndex);this.sliceUploadRunning。delete(partIndex);constprogress=this.sliceUploadSuccess.size/this.partInfo.partNum;this.emmit("progress",progress);if(progress>=1){this.endSliceUpload();}else{这个。_resumeUpload();}}});this.sliceEvent.on("错误",(partIndex:number,err:any)=>{this.emmit("error",err);this.sliceUploadRunning.delete(partIndex);this.status=statusMap.paused;//如果上传出现异常,先暂停上传this.emmit("pause");});常量那个=这个;//创建片段上传实例this.partsArray=Array.from(newArray(this.partInfo.partNum),(x,i)=>newSlice({client:that,partIndex:i+1,}));//开始分片上传this._resumeUpload();}/***上传文件:开始上传或继续上传*@paramfile*@returns{Promise}*/privateasyncuploadFile():Promise{if(this.status!==statusMap.inProcessing){this.status=statusMap.inProcessing;this.emmit("开始");}//开始上传this.startUploadAllSlice();}/***开始上传*@paramfile*@returns{Promise}*/publicasyncstartUpload():Promise{if(this.status!==statusMap.wait){console.log("开始上传状态错误",this.status);this.emmit("错误",errorMap.hasStarted);返回;}this.uploadFile();}//结束切片上传事务privateasyncendSliceUpload(){if(statusMap.canceled===this.status){return;}const标签列表=[];for(constvalofthis.partsArray){tagList.push({partIndex:val.partIndex,partTag:val.partTag,});}//结束分段上传事务constres=awaitaction.endMultipartUpload({tagList});if(!res.hasOwnProperty("err")){this.status=statusMap.success;this.emmit("成功",{resourceId:res.resourceId,preResourceId:res.preResourceId,url:res.path,});}}/***暂停上传*@returns{Promise}*/publicasyncpauseUpload(){//只有在上传文件的时候才可以暂停if(this.status!==statusMap.inProcessing){this.emmit("错误",errorMap.noInProcess);返回;}this.status=statusMap.paused;this.emmit("暂停");}/***切片上传开始*@returns*/private_resumeUpload(){consttodoParts=this.partsArray.filter((part)=>!this.sliceUploadSuccess.has(part.partIndex)&&!this.sliceUploadRunning.有(部分。部分索引));让工作;while(this.sliceUploadRunning.size}*/publicasyncresumeUpload(){if(this.status!==statusMap.paused){this.emmit("error",errorMap.noCanResume);返回;}this.status=statusMap.inProcessing;this.emmit("开始");这个._resumeUpload();}/***废除上传*@returns{Promise<void>}*/publicasyncabortUpload():Promise{//只有在文件正在上传或上传已经暂停时,才能取消上传if(this.status!==statusMap.inProcessing&&this.status!==statusMap.paused){this.emmit("错误",errorMap.noCanCancel);返回;}constresult=awaitaction.abortUpload();//取消上传成功if(!result.err){this.status=statusMap.canceled;this.emmit("中止");this.emmit("进度",0);返回;}this.emmit("错误",result.err);}}导出默认客户端;tsimport{generateMD5}from"../tools/utils";importactionfrom"../action";importClientfrom"./index";classSlice{//以下为独有属性privatesliceFile:Blob;私人md5Content:字符串;私人签名网址:字符串;私有_status:数字;//0失败1成功2进行中3暂停4取消5未开始6错误private_partTag:string;//上传会有一个标签private_partIndex:number;私人客户:客户;//上传实例constructor(config:IsliceConfig){this.client=config.client;this._partIndex=config.partIndex;this._status=statusMap.wait;this._partTag="";}getpartTag(){返回this._partTag;}getstatus(){returnthis._status;}getpartIndex(){returnthis._partIndex;}/***获取分片签名上传url*/privateasyncgetSignatureUrl(){const{file,sliceEvent}=this.client.getConfig();constres=awaitaction.getMultipartUrl(this._partIndex,{headers:{“FileContent-MD5”:this.md5Content,“FileContent-Type”:file.type||“application/octet-stream”,},});如果(!res.err){this.signatureUrl=res.signatureUrl;}else{if(this.getCurrentStatus()===statusMap.canceled){返回;}this._status=statusMap.fail;sliceEvent.emmit("错误",this.partIndex,res.err);}}privategenerateSliceFile(){const{partInfo,file}=this.client.getConfig();conststart=(this._partIndex-1)*partInfo.partSize;letend=start+partInfo.partSize;if(this._partIndex===partInfo.partNum){end=file.size;}this.sliceFile=file.slice(开始,结束);}privateisContinueUpload(){conststatus=this.getCurrentStatus();返回![statusMap.canceled,statusMap.paused].includes(status);}privategetCurrentStatus(){const{status}=this.client.getConfig();返回状态;}privateasyncuploadSlice(){const{file,sliceEvent}=this.client.getConfig();constres=awaitaction.startPartUpload(this.signatureUrl,this.sliceFile,{headers:{“Content-MD5”:this.md5Content,“Content-Type”:file.type||“application/octet-stream”,},});如果(!res.err){this._status=statusMap.success;尝试{this._partTag=JSON.parse(res.headers.etag);}catch(error){this._partTag=res.headers.etag;}sliceEvent.emmit("成功",this._partIndex);}else{if(this.getCurrentStatus()===statusMap.canceled){返回;}this._status=statusMap.fail;sliceEvent.emmit("错误",this._partIndex,res.err);}}//上传切片入口asyncstartUpload(){if(this.isContinueUpload()&&!this.sliceFile){this.generateSliceFile();}if(this.isContinueUpload()&&!this.md5Content&&this.sliceFile){this.md5Content=awaitgenerateMD5(this.sliceFile);}if(this.isContinueUpload()&&!this.signatureUrl&&this.md5Content){awaitthis.getSignatureUrl();}if(this.isContinueUpload()&&this.signatureUrl){awaitthis.uploadSlice();}返回this._status===statusMap.success;}}导出默认切片;3.演示集成importxyUploadfrom"./index.ts";constclient=newxyUpload({file,parallel:3,partSize:2000000,});client.on("progress",(res)=>{console.log("progress",res);});client.on("success",(res)=>{resolve(res);});client.on("error",(res)=>{reject(res);});client.on("start",()=>{console.log("started");});//开始上传client.startUpload();//暂停上传client.pauseUpload();//继续上传client.resumeUpload();//取消上传client.abortUpload();

最新推荐
猜你喜欢