文件上传基本是学习前端路上一定遇到的例子,然而网上能找到的都是单单知足上传这步的案例。大多文章之因此只说上传这步估计是简单易入门,可是实际工做时就会发现上传文件这个功能上是简单的,逻辑上却比较复杂。前端
先说一下需求和功能点:服务器
需求:上传文件到服务器 功能:上传
单这么看是简单的,下面再补充一下:异步
需求2: 须要对图片裁剪压缩 文件必须控制在2MB内 上传文件必须是图片,包含的文件格式有:jpg、gif、png、jpeg、bmp 上传文件到服务器 记录上传文件(包含文件名字、位置、后缀、大小等) 功能: 判断文件格式 裁剪压缩图片 上传 记录数据
也不算复杂,但是这个从业务上来看只是单单的上传功能而已,用户可能还会提出更多要求,如:须要可视化信息(显示上传进度、提示上传成功或失败)、选择上传位置(或云存储,如:七牛)、需选择上传后的文件等其余需求,这就不细说了。学习
仍是说说我遭遇的较为复杂的需求:this
需求3: 上传文件 文件是图片则上传到[图片]仓库,是视频则上传到[视频]仓库,其余则上传到[其余]仓库 须要对图片裁剪压缩 文件大于2MB需启用分片上传 上传至七牛云储存 显示上传进度、提示上传结果 记录上传文件(包含文件名字、位置、后缀、大小等) 功能: 判断文件格式 请求相应仓库上传token --图片-- 得到文件md5(做为文件名) 裁剪压缩图片 --视频-- 判断文件大小,大于2mb开启分片上传 上传 记录数据
这里面包含各类组件间数据传输、异步数据获取等问题尤其恶心...因此我仍是拿需求2这份继续下面话题。code
就目前需求能看出功能点是串行的,以下:orm
function upload(file){ var verify = function(file){ return new Promise(...) }, cut = function(file){ return new Promise(...) }, upload = function(file){ return new Promise(...) }, error = function(){...}; return verify(file).then(cut).then(upload).catch(error); } //file change event upload(e.currentTarget.files[0]).then(/*记录数据*/).catch(...);
若上传组件考虑可扩展性得把逻辑处理
分离出来,逻辑处理
也能以组件方式引入其中并予以调用。但前提是须要约定传入值和返回类型。视频
//上传类 function UploadFile(file){ this.file = file; this.name = file.name; this.size = file.size; this.toFormData = function(data){...}; } var uploader = new Uploader(), verify = function(uploadFile){ return new Promise(...) }, cut = function(uploadFile){ return new Promise(...) }; uploader.precondition.add([verify,cut]); //file change event var key = function(uploadFile){ return new Promise(...) }, uploader.precondition.add(key); //可添加新条件 uploader.upload(new UploadFile(e.currentTarget.files[0])).then(/*记录数据*/).catch(...);
说这么多概念上的东西为的就是记录下工做时的真实状况,须要考虑的不单是功能,还得理解用这个功能的人背后的故事。token