因爲電腦CPU、內存等的限制,可以同時啓動的任務數有必定限制,例如一臺電腦可以執行5個異步任務,可是目前有100個異步任務要執行,那麼如何讓這100個任務無間隔的快速執行完畢呢?
剛遇到這個問題的時候,也是出於懵逼狀態,怎麼處理呢???碰巧的是近期學習了一些Vue的源碼知識,那麼是否是能夠借鑑其思想來解決遇到的這個難題呢?通過一步步分析,肯定答案是確定的。下面從解題思路、知識點及代碼實現來聊一聊實現過程。
上述是整個流程圖,其流程可簡化爲如下幾個步驟:
任務按照固定數量不斷執行,直到全部任務執行完畢。前端
在Vue源碼中,Vue2.x使用Object.defineProperty()實現對數據的幀聽;Vue3.0使用Proxy實現對數據的幀聽。本着趕時髦和Proxy確實優秀的態度,在實現過程當中也應用了Proxy。Proxy做爲一個新的知識點,先了解一下其定義及使用方法。
Proxy中文意思是「代理」,是在目標對象之間架設一層「攔截」,從而能夠修改某些操做的默認行爲。Proxy共支持十三種攔截操做:get、set、has、deleteProperty、ownKeys、getOwnPropertyDescriptor、defineProperty、preventExtensions、getPrototypeOf、isExtensible、setPrototypeOf、apply、construct。
function testProxy(obj) { return new Proxy(obj, { get: (target, key) => { console.log(`我被get攔截器攔截了,攔截的屬性是${key}`); }, set: (target, key, value) => { console.log(`我被set攔截器攔截了,攔截的屬性是${key}, 新值是${value}`); target[key] = value; } }); } const testObj = { a: 10 }; const proxy = testProxy(testObj); proxy.a = 100;
詳細用法能夠參考阮一峯大佬的「ECMAScript 6入門」。
首先定義兩個任務隊列,task1爲開始執行的一批任務,task2中爲後續添加進去的任務。
const task1 = [1, 2, 3]; const task2 = [4, 5, 6, 7, 8];
利用Proxy將數據變爲可幀聽狀態
/** * 監聽模塊,監聽對應數組的變化,保證其始終有必定長度的內容在運行 * * @param {Array} initArr 定長任務的數組 * @param {Function} callback 對應的回調函數 */ function watcher(initArr, callback) { const proxy = new Proxy(initArr, { set(target, key, value, receiver) { target[key] = value; callback(value, key, receiver); } }); return proxy; }
/** * 異步任務的運行邏輯 * * @param {number} taskIndex 異步任務的序號 * @param {number} index 當前任務在定長任務的序號 * @param {Proxy} proxy Proxy實例 */ function asyncTask(taskIndex, index, proxy) { console.log(`${index}索引處的任務${taskIndex}開始執行`); return new Promise(resolve => { setTimeout(() => { console.log(`${index}索引處的任務${taskIndex}執行完畢`); // 當任務隊列2中還有任務時,進入隊列替換任務1中執行完的任務 if (task2.length > 0) { proxy[index] = task2.shift(); } }, 1000 + 2000 * Math.random()); }); }
const proxy = watcher(task1, asyncTask); task1.forEach((taskIndex, index) => asyncTask(taskIndex, index, proxy)); }
經過結果能夠看到,當一個任務完成時馬上將有一個新的任務進入。
0索引處的任務1開始執行 1索引處的任務2開始執行 2索引處的任務3開始執行 0索引處的任務1執行完畢 0索引處的任務4開始執行 2索引處的任務3執行完畢 2索引處的任務5開始執行 1索引處的任務2執行完畢 1索引處的任務6開始執行 0索引處的任務4執行完畢 0索引處的任務7開始執行 2索引處的任務5執行完畢 2索引處的任務8開始執行 1索引處的任務6執行完畢 0索引處的任務7執行完畢 2索引處的任務8執行完畢
針對此類問題的處理方式,各位大佬有新的思路與方法歡迎留言,咱們一塊兒討論,共同進步。
1.若是以爲這篇文章還不錯,來個分享、點贊吧,讓更多的人也看到數組
2.關注公衆號執鳶者,領取學習資料(前端「多兵種」資料),按期爲你推送原創深度好文app