国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > JavaScript > 正文

淺談關于JS下大批量異步任務按順序執行解決方案一點思考

2024-05-06 15:43:25
字體:
來源:轉載
供稿:網友

前言

最近需要做一個瀏覽器的, 支持大體積文件上傳且要支持斷點續傳的上傳組件, 本來以為很容易的事情, 結果碰到了一個有意思的問題:

循環執行連續的異步任務, 且后一個任務需要等待前一個任務的執行狀態

這么說可能有點空泛, 以我做的組件舉例:

這個組件本意是為了上傳大體積視頻, 和支持斷點續傳, 因為動輒幾個G的視頻不可能直接把文件讀進內存, 只能分片發送(考慮到實際網絡狀態, 每次發送大小定在了4MB), 而且這么做也符合斷點續傳的思路.

組件工作流程如下:

    選定上傳文件后, 從H5原生upload組件里取得文件的blob對象  (同步) 通過blob對象的slice方法把文件切片  (同步) 新建一個Filereader對象, 通過Filereader的readAsArrayBuffer方法讀取步驟2中生成的slice  (異步) 如果步驟3的buffer讀取成功(通過監控Filereader的onload事件), 則ajax發送步驟3中的buffer  (異步) 如果ajax發送成功, 且服務器儲存完成, 會向客戶端發回一個成功狀態碼, 如果ajax的response中存在這個狀態碼, 則進行下一次切片發送  (異步)

從組件工作流程可以發現, 3,4,5中的連續異步任務, 必須要按順序進行, 且每一步任務間存在相互依賴, 最后還要對這些步驟進行多次循環.

如果只是處理單次的連續異步任務, 通過promise鏈式調用即可, 但是要循環執行這樣的連續異步任務讓我想了很久.

后來google了很久也沒發現解決方案, 無奈下閉門造車了2天, 想出了3套方案, 權當拋磚引玉, 希望各位給出更好建議

3套方案的核心思想相同, 類似觀察者模式, 來控制循環的進行, 區別在于循環的實現不同, 實際上這3套方案也是我自我否定的過程, 不斷思考更好的方法, 整個組件代碼略長, 在此只挑出問題相關部分, 且省略錯誤處理部分

方案1

依然以上傳組件舉例

//循環狀態標記,0為初始狀態,1為正常,2為出錯let status = 0;/* 新建Filereader,讀取文件切片,返回一個promise* 把讀取成功的arraybuffer通過reslove傳出*/const createReader = ()=> { return new Promise ((reslove, reject)=> {  let reader = new Filereader();  ...  reader.onload = ()=> {   reslove(reader.result)  }  reader.onerror = ()=> reject() })}// ajax發送createReader方法讀取到的Buffconst createXhr = ()=> { const xhr= new XMLHttpRequest(); return new Promise ((reslove, reject)=> {  ...  xhr.onreadystatechange= ()=> {   ...   //如果readyState == 4,status == 200且服務器的狀態碼存在,更改全局標記為1   status = 1;   reslove()  } })}//每一輪循環開始前都檢查一次全局狀態標記const checkStatus = ()=> { ... if (status == 1) {  loop() }}//循環過程的鏈式調用const loop = ()=> { createReader().then(()=> createXhr()).then(()=> checkStatus());}            
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 永嘉县| 迁西县| 阳信县| 崇信县| 二连浩特市| 南宁市| 兰溪市| 宣武区| 资兴市| 德令哈市| 衡阳县| 静乐县| 泌阳县| 宕昌县| 班玛县| 凤山市| 喀喇沁旗| 文水县| 手机| 梁河县| 通海县| 恩施市| 平定县| 信丰县| 澳门| 攀枝花市| 苏尼特左旗| 尼玛县| 山阴县| 崇州市| 涞源县| 荥阳市| 威远县| 宜兰县| 辽源市| 临江市| 巴马| 砀山县| 望都县| 东源县| 岳西县|