iT邦幫忙

2023 iThome 鐵人賽

DAY 5
0
自我挑戰組

JavaScript 是什麼?可以吃嗎?系列 第 5

Day5 - 函數應用- 併發任務

  • 分享至 

  • xImage
  •  

嗨大家好,我是Eric,假設當我們有大量異步函數(api請求)要同時執行,我們不可能一次請求(網站可能會崩潰XD),所以我們可以限制一次請求的數量(比如10個),這樣可以有效提升 User 的用戶體驗,這就來談談實現這個需求的函數應用 - 併發任務。

什麼是併發?

簡單來說,併發就是同時執行多個任務。與串行(一個接一個地執行)相比,併發可以更高效。

example:

我們通過一個例子來說明如何實現併發任務。
假設我們有一個任務列表,每個任務都是一個異步函數,我們想要同時執行其中的一部分。

mockTask 函數
首先,我們需要模擬一些異步任務。我們使用 mockTask 函數來生成這些任務。

function mockTask(count) {
    const tasks = [];

    for (let i = 0; i < count; i++) {
        const asyncTask = async function() {
            const startTime = Date.now();
            console.log(`任務 ${i + 1}:任務開始...`);
            
            // 模擬異步操作,比如等待1到5秒
            const waitTime = Math.floor(Math.random() * 5000) + 1000;
            await new Promise(resolve => setTimeout(resolve, waitTime));

            const endTime = Date.now();
            const elapsedTime = endTime - startTime;

            console.log(`任務 ${i + 1}:完成,耗時 ${elapsedTime} ms`);
        };
    
        tasks.push(asyncTask);
    }
    return tasks;
}

接著,我們使用 paralleTask 函數來管理這些任務。

function paralleTask(tasks, parallelCount = 2) {
    return new Promise((resolve, reject) => {
        
        // 如果沒有任務,直接 resolve 任務完成
        if(tasks.length === 0) {
            resolve();
            return;
        }
        
        let nextIndex = 0; // 記錄下一個任務的索引
        let completedCount = 0; // 記錄已經完成的任務數量

        // 輔助函數,用於執行任務
        function _run() {
            // 運行下一個任務
            const task = tasks[nextIndex];
            nextIndex++;
            task().then(() => {
                completedCount++;
                if (nextIndex < tasks.length) {
                    // 如果還有任務,運行下一個
                    _run();

                }else if(completedCount === tasks.length) {
                    // 完成的任務數量等於任務總數(完成所有任務),resolve
                    resolve();
                }
            })
        }

        // 依據併發數量,啟動任務
        for (let i = 0; i < parallelCount && i < tasks.length ; i++) {
            // 執行任務
            _run();
        }
    });
}

組合使用
最後,我們可以這樣使用這兩個函數:

const task = mockTask(100);
paralleTask(task, 4).then(() => {
    console.log('所有任務都已經完成');
});

結論

透過使用 mockTask 和 paralleTask,我們可以方便地模擬和管理多個異步請求。這種併發模式不僅使我們能夠更高效,而且也提供了一種更加靈活的方式來執行任務。

這就是今天的全部內容,明天見~~


上一篇
Day4 - 瀏覽器渲染原理解析
下一篇
Day6 - 進度監聽器 XHR
系列文
JavaScript 是什麼?可以吃嗎?20
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言