茄子在线看片免费人成视频,午夜福利精品a在线观看,国产高清自产拍在线观看,久久综合久久狠狠综合

    <s id="ddbnn"></s>
  • <sub id="ddbnn"><ol id="ddbnn"></ol></sub>

  • <legend id="ddbnn"></legend><s id="ddbnn"></s>

    JS中setTimeout的巧妙用法前端函數節(jié)流
    來源:易賢網 閱讀:1315 次 日期:2016-07-16 14:10:31
    溫馨提示:易賢網小編為您整理了“JS中setTimeout的巧妙用法前端函數節(jié)流”,方便廣大網友查閱!

    這篇文章主要介紹了JS中setTimeout的巧妙用法前端函數節(jié)流 的相關資料,需要的朋友可以參考下

    什么是函數節(jié)流?

    函數節(jié)流簡單的來說就是不想讓該函數在很短的時間內連續(xù)被調用,比如我們最常見的是窗口縮放的時候,經常會執(zhí)行一些其他的操作函數,比如發(fā)一個ajax請求等等事情,那么這時候窗口縮放的時候,有可能連續(xù)發(fā)多個請求,這并不是我們想要的,或者是說我們常見的鼠標移入移出tab切換效果,有時候連續(xù)且移動的很快的時候,會有閃爍的效果,這時候我們就可以使用函數節(jié)流來操作。大家都知道,DOM的操作會很消耗或影響性能的,如果是說在窗口縮放的時候,為元素綁定大量的dom操作的話,會引發(fā)大量的連續(xù)計算,比如在IE下,過多的DOM操作會影響瀏覽器性能,甚至嚴重的情況下,會引起瀏覽器崩潰的發(fā)生。這個時候我們就可以使用函數節(jié)流來優(yōu)化代碼了~

    函數節(jié)流的基本原理:

    使用一個定時器,先延時該函數的執(zhí)行,比如使用setTomeout()這個函數延遲一段時間后執(zhí)行函數,如果在該時間段內還觸發(fā)了其他事件,我們可以使用清除方法 clearTimeout()來清除該定時器,再setTimeout()一個新的定時器延遲一會兒執(zhí)行。

    最近在某團隊忙于一個項目,有這么一個頁面,采用傳統(tǒng)模式開發(fā)(吐槽它為什么不用React),它的DOM操作比較多,然后性能是比較差的,尤其當你縮放窗口時,可怕的事情發(fā)生了,出現了卡頓,甚至瀏覽器癱瘓。為什么呢?

    由于該頁面的DOM操作非常多,故窗口縮放每一幀時都會觸發(fā)函數的執(zhí)行,連續(xù)的重新DOM操作,這樣對瀏覽器的開銷是非常大的。既然在窗口縮放時,會讓瀏覽器重新計算DOM,那么我們?yōu)槭裁床豢梢宰孌OM的計算延時呢,讓窗口停止縮放后才重新計,這樣不就節(jié)省了瀏覽器的開銷,達到優(yōu)化的效果了嗎?

    知識準備

    1. setTimeout(code,millisec) 當然就是本文的主角了。

    setTimeout() 方法用于在指定的毫秒數后調用函數或計算表達式。

    code必需。要調用的函數后要執(zhí)行的 JavaScript 代碼串。

    millisec必需。在執(zhí)行代碼前需等待的毫秒數。

    提示:setTimeout() 只執(zhí)行 code 一次。如果要多次調用,請使用 setInterval() 或者讓 code 自身再次調用 setTimeout()。

    廣泛應用于定時器,輪播圖,動畫效果,自動滾動等等。

    2. clearTimeout(id_of_setTimeout)

    參數 id_of_settimeout由 setTimeout() 返回的 ID 值。該值標識要取消的延遲執(zhí)行代碼塊。

    3. fun.apply(thisArg[, argsArray])

    apply() 方法在指定 this 值和參數(參數以數組或類數組對象的形式存在)的情況下調用某個函數

    該函數的語法與call()方法幾乎相同,唯一的區(qū)別在于,call()方法接受的是一個參數列表,而apply()接受的是一個包含多個參數數組的(或類數組對象)。

    參數

    thisArg

    在 fun 函數運行時指定的 this 值。需要注意的是,指定的 this 值并不一定是該函數執(zhí)行時真正的 this 值,如果這個函數處于非嚴格模式下,則指定為 null 或 undefined 時會自動指向全局對象(瀏覽器中就是window對象),同時值為原始值(數字,字符串,布爾值)的 this 會指向該原始值的自動包裝對象。

    argsArray

    一個數組或者類數組對象,其中的數組元素將作為單獨的參數傳給 fun 函數。如果該參數的值為null 或 undefined,則表示不需要傳入任何參數。從ECMAScript 5 開始可以使用類數組對象。

    在調用一個存在的函數時,你可以為其指定一個 this 對象。 this 指當前對象,也就是正在調用這個函數的對象。 使用 apply, 你可以只寫一次這個方法然后在另一個對象中繼承它,而不用在新對象中重復寫該方法。

    4. fun.call(thisArg[, arg1[, arg2[, ...]]])

    該 方法在使用一個指定的this值和若干個指定的參數值的前提下調用某個函數或方法.

    參數

    thisArg

    在fun函數運行時指定的this值。需要注意的是,指定的this值并不一定是該函數執(zhí)行時真正的this值,如果這個函數處于非嚴格模式下,則指定為null和undefined的this值會自動指向全局對象(瀏覽器中就是window對象),同時值為原始值(數字,字符串,布爾值)的this會指向該原始值的自動包裝對象。

    arg1, arg2, ...

    指定的參數列表。

    當調用一個函數時,可以賦值一個不同的 this 對象。this 引用當前對象,即 call 方法的第一個參數。通過 call 方法,你可以在一個對象上借用另一個對象上的方法,比如Object.prototype.toString.call([]),就是一個Array對象借用了Object對象上的方法。

    作用:

    使用call方法調用父構造函數

    使用call方法調用匿名函數

    使用call方法調用匿名函數并且指定上下文的'this'

    這里插個題外話:

    apply 與 call() 非常相似,不同之處在于提供參數的方式。apply 使用參數數組而不是一組參數列表。apply 可以使用數組字面量(array literal),如 fun.apply(this, ['eat', 'bananas']),或數組對象, 如 fun.apply(this, new Array('eat', 'bananas'))。你也可以使用 arguments 對象作為 argsArray 參數。 arguments 是一個函數的局部變量。 它可以被用作被調用對象的所有未指定的參數。 這樣,你在使用apply函數的時候就不需要知道被調用對象的所有參數。 你可以使用arguments來把所有的參數傳遞給被調用對象。 被調用對象接下來就負責處理這些參數。

    從 ECMAScript 第5版開始,可以使用任何種類的類數組對象,就是說只要有一個 length 屬性和[0...length) 范圍的整數屬性。例如現在可以使用 NodeList 或一個自己定義的類似 {'length': 2, '0': 'eat', '1': 'bananas'} 形式的對象。

    call, apply方法區(qū)別是,從第二個參數起, call方法參數將依次傳遞給借用的方法作參數, 而apply 直接將這些參數放到一個數組中再傳遞, 最后借用方法的參數列表是一樣的.

    應用場景:當參數明確時可用call, 當參數不明確時可用apply給合arguments

    現在先給出一個例子

    總所皆知,onscolll,onresize等是非常耗性能,窗口縮放時打印數字。

    var count = ;

    window.onresize = function () {

    count++;

    console.log(count);

    }

    在chrome瀏覽器中伸縮瀏覽器窗口大小,打印如下

    這顯然不是我們想要的,那如果我們換成ajax請求的話,那么就會縮放一次窗口會連續(xù)觸發(fā)多次ajax請求,下面我們試著使用函數節(jié)流的操作試試一下;當然加個settimeout()的定時器就好了,

    第一種封裝方法

    var count = ;

    function oCount() {

    count++;

    console.log(count);

    }

    window.onresize = function () {

    delayFun(oCount)

    };

    function delayFun(method, thisArg) {

    clearTimeout(method.props);

    method.props = setTimeout(function () {

    method.call(thisArg)

    }, )

    }

    第二種封裝方法

    構造一個閉包,使用閉包的方式形成一個私有的作用域來存放定時器timer, timer是通過傳參數的形式引入的。

    var count = ;

    function oCount() {

    count++;

    console.log(count);

    }

    var funs= delayFun(oCount,);

    window.onresize = function () {

    funs()

    };

    function delayFun(func, wait) {

    var timer = null;

    return function () {

    var context = this,

    args = arguments;

    clearTimeout(timer);

    timer = setTimeout(function () {

    func.apply(context, args);

    }, wait)

    };

    }

    對第二種方法優(yōu)化一下,性能會更好

    這里返回一個函數,如果它被不間斷地調用,它將不會得到執(zhí)行。該函數在停止調用 N 毫秒后,再次調用它才會得到執(zhí)行。如果有傳遞 ‘immediate' 參數,會馬上將函數安排到執(zhí)行隊列中,而不會延遲。

    function delayFun (func, wait, immediate) {

    var timeout;

    return function() {

    var context = this, args = arguments;

    var later = function() {

    timeout = null;

    if (!immediate) func.apply(context, args);

    };

    var callNow = immediate && !timeout;

    clearTimeout(timeout);

    timeout = setTimeout(later, wait);

    if (callNow) func.apply(context, args);

    };

    };

    // 用法

    var myEfficientFn = delayFun (function() {

    // 所有繁重的操作

    }, );

    window.addEventListener('resize', myEfficientFn);

    函數不允許回調函數在指定時間內執(zhí)行多于一次。當為一個會頻繁觸發(fā)的事件分配一個回調函數時,該函數顯得尤為重要。

    setTimeout這么厲害,那么我們是可以在項目中大量使用嗎?

    我個人是不建議的,在我們業(yè)務中,基本上是禁止在業(yè)務邏輯中使用setTimeout的,因為我所看到的很多使用方式都是一些問題好解決,setTimeout作為一個hack的方式。

    例如,當一個實例還沒有初始化的前,我們就使用這個實例,錯誤的解決辦法是使用實例時加個setTimeout,確保實例先初始化。

    為什么錯誤?這里其實就是使用hack的手段

    第一是埋下了坑,打亂模塊的生命周期

    第二是出現問題時,setTimeout其實是很難調試的。

    我認為正確的使用方式是,看看生命周期(可參考《關于軟件的生命周期 》),把實例化提到使用前執(zhí)行。

    有關JS中setTimeout的巧妙用法前端函數節(jié)流,小編就給大家介紹到這里,希望對大家有所幫助!

    更多信息請查看網絡編程

    2026上岸·考公考編培訓報班

    • 報班類型
    • 姓名
    • 手機號
    • 驗證碼
    關于我們 | 聯系我們 | 人才招聘 | 網站聲明 | 網站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點 | 投訴建議
    工業(yè)和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網安備53010202001879號 人力資源服務許可證:(云)人服證字(2023)第0102001523號
    聯系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關注公眾號:hfpxwx
    咨詢QQ:1093837350(9:00—18:00)版權所有:易賢網