JavaScript >> Javascript 文檔 >  >> JavaScript

JavaScript 中的定時數組處理

不久前,我在博客中介紹了一種異步處理 JavaScript 數組以避免鎖定瀏覽器(並進一步避免顯示長時間運行的腳本對話框)的方法。 chunk() 該原始博客文章中引用的函數如下:

function chunk(array, process, context){
    var items = array.concat();   //clone the array
    setTimeout(function(){
        var item = items.shift();
        process.call(context, item);

        if (items.length > 0){
            setTimeout(arguments.callee, 100);
        }
    }, 100);
}

此方法是一個示例實現,並且有幾個性能問題。首先,延遲的大小對於大型數組來說太長了。對包含 100 個項目的數組使用 100 毫秒延遲意味著處理至少需要 10,000 毫秒或 10 秒。延遲實際上應該減少到 25 毫秒。這是我建議避免瀏覽器計時器分辨率問題的最小延遲。 Internet Explorer 的計時器分辨率為 15 毫秒,因此指定 15 毫秒將為 0 或 15,具體取決於上次設置系統時間的時間。你真的不想要 0,因為在下一批 JavaScript 代碼開始處理之前,這沒有給 UI 更新足夠的時間。指定 25 毫秒的延遲可以保證至少延遲 15 毫秒,最多延遲 30 毫秒。

儘管如此,延遲 25 毫秒,處理一個包含 100 個項目的數組至少需要 2,500 毫秒或 2.5 秒,仍然相當長。實際上,chunk() 的全部意義 是為了確保您不會達到長時間運行的腳本限制。問題是長時間運行的腳本限制在用戶體驗到 UI 凍結之後很久才開始。

改進空間

Jakob Nielsen 在他的論文中指出,響應時間:三個重要限制 ,即 0.1 秒(100 毫秒)“大約是讓用戶感覺到系統正在即時做出反應的極限,這意味著除了顯示結果之外不需要特殊的反饋。”由於在 JavaScript 執行時 UI 無法更新,這意味著您的 JavaScript 代碼的連續執行時間不應超過 100 毫秒。此限制遠小於網絡瀏覽器中的長時間運行腳本限制。

我實際上會更進一步,並說任何腳本都不應該連續運行超過 50 毫秒。在此之上,您的趨勢接近極限,可能會無意中影響用戶體驗。我發現 50 毫秒對於大多數 JavaScript 操作來說已經足夠了,並且在代碼執行時間過長時是一個很好的截止點。

使用這些知識,您可以創建 chunk() 的更好版本 功能:

//Copyright 2009 Nicholas C. Zakas. All rights reserved.
//MIT Licensed
function timedChunk(items, process, context, callback){
    var todo = items.concat();   //create a clone of the original

    setTimeout(function(){

        var start = +new Date();

        do {
             process.call(context, todo.shift());
        } while (todo.length > 0 && (+new Date() - start < 50));

        if (todo.length > 0){
            setTimeout(arguments.callee, 25);
        } else {
            callback(items);
        }
    }, 25);
}

這個新版本的函數插入了一個 do-while 循環將持續處理項目,直到沒有其他項目要處理或代碼已執行 50 毫秒。一旦該循環完成,邏輯完全相同:如果要處理更多項目,則創建一個新計時器。添加回調函數可以在處理完所有項目時進行通知。

我設置了一個測試來比較這兩種方法,因為它們處理了一個包含 500 個項目的數組,結果非常驚人:timedChunk() 經常花費不到 chunk() 10% 的時間 完全處理所有項目。自己試試吧。請注意,這兩個進程都不會導致瀏覽器顯示為凍結或鎖定。

結論

即使原來的 chunk() 方法對於處理小型數組很有用,但在處理大型數組時會影響性能,因為完全處理數組需要花費大量時間。新的 timedChunk() 方法更適合在不影響用戶體驗的情況下,在最短的時間內處理大型數組。


Tutorial JavaScript 教程
  1. 為什麼 React 會重新渲染我未更改的列表項?我怎樣才能防止這種情況?

  2. 從頭開始的 Vuejs 反應性

  3. Angular:生命週期鉤子是組件可用的輸入數據

  4. 環境變量 - Webstorm &Nodemon

  5. 狀態機計數器

  6. 今天我學習了關於拆分登陸頁面

  7. Nodal:在 Node.js 中輕鬆創建 API 服務的教程

  1. 使用 command.js 構建命令行程序

  2. 如何在 Ubuntu 20.04 上安裝 Node.js 和 NPM

  3. MoleculerJS 如何為 Dyte 提供動力!

  4. Node 中的模塊管理

  5. 帶有 ProseMirror 和同步數據庫的基於 Web 的協作文本編輯器

  6. 電子大冒險:第 39 集:鍵盤快捷鍵修改鍵

  7. JavaScripts fetch API 的備忘單

  1. 使用 JavaScript 或 jQuery 檢測 Mac OS X 或 Windows 計算機的最佳方法

  2. 創建自定義 Chart.js 圖例樣式

  3. 我的第一篇文章是關於 lambda resize images

  4. 如何檢查 JavaScript 對像中是否存在屬性