Given an array of asyncronous functions functions and a pool limit n, return an asyncronous function promisePool. It should return a promise that resolves when all the input functions resolve.
給定一個非同步函式陣列 functions 和一個 pool limit n,回傳一個非同步函式 promise Pool。 它應該回傳一個在所有輸入函式結束的結果。
Pool limit is defined as the maximum number promises that can be pending at once. promisePool should begin execution of as many functions as possible and continue executing new functions when old promises resolve. promisePool should execute functions[i] then functions[i + 1] then functions[i + 2], etc. When the last promise resolves, promisePool should also resolve.
Pool limit 被定義可以一次執行的 promises 次數。 promisePool 應該盡可能執行多個函式,並在舊的 promises 解決之後, promisePool 應該執行 functions[i] => functions[i + 1] => functions[i + 2] 當最後一個 promise 解決時,promisePool 也應該解決。
For example, if n = 1, promisePool will execute one function at a time in series. However, if n = 2, it first executes two functions. When either of the two functions resolve, a 3rd function should be executed (if available), and so on until there are no functions left to execute.
例如,如果 n = 1,promisePool 將依次執行一個函式。 但是,如果 n = 2,它首先執行兩個函式。 當兩個函式中的任何一個解決時,應該執行第三個函式(如果可用),依此類推,直到沒有要執行的函式為止。
You can assume all functions never reject. It is acceptable for promisePool to return a promise that resolves any value.
你可以假設所有功能都不會拒絕。 promisePool 可以接受回傳一個 promise 中解決的任何值。
Example 1:
Input: functions = [ () => new Promise(res => setTimeout(res, 300)), () => new Promise(res => setTimeout(res, 400)), () => new Promise(res => setTimeout(res, 200)) ] n = 2 Output: [[300,400,500],500]
Example 2:
Input: functions = [ () => new Promise(res => setTimeout(res, 300)), () => new Promise(res => setTimeout(res, 400)), () => new Promise(res => setTimeout(res, 200)) ] n = 5 Output: [[300,400,200],400]
Example 3:
Input: functions = [ () => new Promise(res => setTimeout(res, 300)), () => new Promise(res => setTimeout(res, 400)), () => new Promise(res => setTimeout(res, 200)) ] n = 1 Output: [[300,700,900],900]
solution:
宣告 queue 為一個新的 set() 物件用於儲存正在執行的任務,同時 resolved 陣列用於儲存已完成的任務的結果。
將 functions 中的 task 依序存放到 queue 中,同時將 res 放入 resolved 並從 queue 中刪除任務。
檢查目前正在執行的 task 數量,如果已達到設定的最大數量「n」,則使用「await Promise.race(queue)」等待任一個任務完成。
最後使用「await Promise.all(queue)」將等待所有剩餘的 task 完成。
回傳儲存了所有完成任務結果的「resolved」陣列。
Code 1: BigO(n)
var promisePool = async function(functions, n) { //使用 Set() 來儲存正在執行的任務 let queue = new Set(), resolved = [] for (const task of functions) { //將正在執行的任務加入隊列中 const x = task().then((res) => { //任務執行完成後放入resolved resolved.push(res) //完成後移除正在執行的列隊中 queue.delete(x) }) queue.add(x) //控制執行的最大數量 if (queue.size >= n) { await Promise.race(queue) } } //執行完所有任務後才回傳執行結果 await Promise.all(queue) return resolved; };
FlowChart:
Example 1
n = 2 Promise.race(() => new Promise(res => setTimeout(res, 300))) //300 Promise.race(() => new Promise(res => setTimeout(res, 400))) //400 Promise.all(() => new Promise(res => setTimeout(res, 200))) //300 + 200 = 500 Output: [[300,400,500],500]
Example 2
n = 5 Promise.all(() => new Promise(res => setTimeout(res, 300))) //300 Promise.all(() => new Promise(res => setTimeout(res, 400))) //400 Promise.all(() => new Promise(res => setTimeout(res, 200))) //200 Output: [[300,400,200],400]
Example 3
n = 1 Promise.race(() => new Promise(res => setTimeout(res, 300))) //300 Promise.race(() => new Promise(res => setTimeout(res, 400))) //300 + 400 = 700 Promise.race(() => new Promise(res => setTimeout(res, 200))) //700 + 200 = 900 Output: [[300,700,900],900]