函數節流控制函數被頻繁調用

来源:http://www.cnblogs.com/weboey/archive/2017/11/10/7815628.html
-Advertisement-
Play Games

函數被頻繁調用場景 Js中的函數大多數情況下都是由用戶主動調用觸發的,一般不會遇到性能相關的問題。但在一些少數情況下,函數的觸發不是由用戶直接控制。在這些場景下,函數有可能被非常頻繁地調用,而造成大的性能問題。 比如以下場景: 函數節流的原理: 函數節流的原理就是使用定時器來控制函數調用。當觸發一個 ...


函數被頻繁調用場景

Js中的函數大多數情況下都是由用戶主動調用觸發的,一般不會遇到性能相關的問題。但在一些少數情況下,函數的觸發不是由用戶直接控制。在這些場景下,函數有可能被非常頻繁地調用,而造成大的性能問題。

比如以下場景:

  1. window.onresize事件。如果我們給window對象綁定了resize事件,當瀏覽器視窗大小被改變的時候,這個事件的觸發的頻率非常高。(其實任何元素節點也是可以綁定resize事件的,如何實現可參考 如何給div綁定resize事件。也可以使用第三方庫 resize-observer-polyfill)
  2. mousemove事件。
  3. DOM變化觀察者MutationObserver。dom的變化造成觀察者對象被頻繁觸發。

函數節流的原理:

函數節流的原理就是使用定時器來控制函數調用。當觸發一個事件函數時,先setTimout讓這個事件延遲一會再執行,如果在這個時間間隔內又觸發了事件,那我們就clear掉原來的定時器,再setTimeout一個新的定時器延遲一會執行。

代碼實現

var throttle=function(fn,interval){
    var _self=fn; //保存需要被延長執行的函數引用
    var timer;
    var firstTime=true;   //是否是第一次調用

    return function (){
        var args=arguments;
        var _this=this;
        if(firstTime){  //如果第一次調用,不需要延遲執行
            _self.apply(_this,args);
            return firstTime = false;
        }
        if(timer){  //如果定時器還在,說明前一次延遲執行還沒有完成
            return false;
        }
        timer = setTimeout(function(){  //延遲一段時間執行
            clearTimeout(timer);
            timer=null;
            _self.apply(_this,args);
        },interval || 500);
    };
};
View Code 方式1
var throttle2 = function (callback, delay, trailingTimeout) {
    var leadingCall = false,
        trailingCall = false,
        lastCallTime = 0;

    function resolvePending() {
        if (leadingCall) {
            leadingCall = false;
            callback();
        }
        if (trailingCall) {
            proxy();
        }
    }

    function timeoutCallback() {
        requestAnimationFrame(resolvePending);
    }

    function proxy() {
        var timeStamp = Date.now();
        if (leadingCall) {
            if (timeStamp - lastCallTime < trailingTimeout) {
                return;
            }
            trailingCall = true;
        } else {
            leadingCall = true;
            trailingCall = false;
            setTimeout(timeoutCallback, delay);
        }
        lastCallTime = timeStamp;
    }
    return proxy;
};
View Code 方式2

代碼測試

window.onresize=throttle(function(){
    console.log(1);
},1000);

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 如何通過使用Q來併發執行多個promises呢? 上面的代碼輸出結果為1。很顯然,你不能簡單地將各個promises都放到一個Q()函數里來執行,這樣只有第一個promise會被正確地執行,剩餘的都會被忽略掉。 你可以使用Q.all來代替上面的方法,它們之間的主要區別是前者將每個promise單獨作 ...
  • 下麵以現實場景作為情境。 基礎知識,理解git中的幾個區域 本地代碼已經add,未commit 修改本地工作目錄中的readme.md,添加文字"第一次修改" 然後查看下狀態 進行Add操作,並查看狀態 這時候,變動進入了緩存區(Index) 但是我們突然發現我們改動錯了,其實我是想改動 文件。 方 ...
  • ...
  • 瞭解瞭解 jQuery是一個快速,小巧,功能豐富的JavaScript庫。它使諸如HTML文檔遍歷和操縱,事件處理,動畫和Ajax等事情變得簡單得多,而且易於使用的API可以在多種瀏覽器中使用。 一、 什麼是JQuery? jQuery是一個JavaScript函數庫。 jQuery是一個輕量級的" ...
  • 在一些項目需求中需要父組件向子組件動態傳值,比如我這裡的需求是,父組件動態通過axios獲取返回的圖片url數組然後傳給子組件,上傳圖片的子組件拿到該數組後進行遍歷並展示圖片 方法有兩種, 方法一: props傳值,這裡註意一個問題,傳過來的值需要用watch監聽並賦值,否則這裡獲取到的是空數組 父 ...
  • 1.v-if&v-else&v-show v-if用來判斷是否載入html的DOM,v-if和v-else一般是一起用的。 v-show相當於display,DOM已經載入出來了,這個是判斷它要不要顯現出來 2.v-for,這個主要是迴圈輸出的問題,js里不是有for..in...迴圈麽?這個跟那個 ...
  • 今天整理文件時找到了之前做的一些js練習,裡面的帶縮略圖的圖片輪換正好跟我之前做的banner輪播有點像。就又看了一遍,添加了一些註釋。 效果如下: 代碼: 1 <!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="utf-8" ...
  • 參考:http://blog.csdn.net/xieweikun7/article/details/52766676 1、首先,下載嘛 Echarts http://echarts.baidu.com/download.html 百度地圖 http://lbsyun.baidu.com/ >>>> ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...