文件上傳基本是學習前端路上一定遇到的例子,然而網上能找到的都是單單知足上傳這步的案例。大多文章之因此只說上傳這步估計是簡單易入門,可是實際工做時就會發現上傳文件這個功能上是簡單的,邏輯上卻比較複雜。前端
先說一下需求和功能點:服務器
需求:上傳文件到服務器 功能:上傳
單這麼看是簡單的,下面再補充一下:異步
需求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