亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

JS中setTimeout的巧妙用法前端函數節流

2019-11-20 10:21:09
字體:
來源:轉載
供稿:網友

什么是函數節流?

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

函數節流的基本原理:

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

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

由于該頁面的DOM操作非常多,故窗口縮放每一幀時都會觸發函數的執行,連續的重新DOM操作,這樣對瀏覽器的開銷是非常大的。既然在窗口縮放時,會讓瀏覽器重新計算DOM,那么我們為什么不可以讓DOM的計算延時呢,讓窗口停止縮放后才重新計,這樣不就節省了瀏覽器的開銷,達到優化的效果了嗎?

知識準備

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

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

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

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

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

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

2. clearTimeout(id_of_setTimeout)

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

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

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

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

參數

thisArg

在 fun 函數運行時指定的 this 值。需要注意的是,指定的 this 值并不一定是該函數執行時真正的 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值并不一定是該函數執行時真正的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方法區別是,從第二個參數起, call方法參數將依次傳遞給借用的方法作參數, 而apply 直接將這些參數放到一個數組中再傳遞, 最后借用方法的參數列表是一樣的.

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

現在先給出一個例子

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

var count = ;window.onresize = function () {count++;console.log(count);}

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

這顯然不是我們想要的,那如果我們換成ajax請求的話,那么就會縮放一次窗口會連續觸發多次ajax請求,下面我們試著使用函數節流的操作試試一下;當然加個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)};}

對第二種方法優化一下,性能會更好

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

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); 

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

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

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

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

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

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

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

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

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
黑人精品xxx一区| 国产69精品久久久久久| 狠狠久久五月精品中文字幕| 久久成人国产精品| 欧美与欧洲交xxxx免费观看| 欧美一区二区三区免费视| 91av免费观看91av精品在线| 国产一区二区三区在线观看网站| 欧美理论片在线观看| 清纯唯美亚洲综合| 91国产美女视频| 亚洲偷欧美偷国内偷| 欧美亚洲伦理www| 精品国产乱码久久久久久婷婷| 亚洲激情电影中文字幕| 成人黄色免费看| 欧美精品日韩www.p站| 97香蕉久久夜色精品国产| 欧美性极品少妇精品网站| 夜夜嗨av一区二区三区四区| 国产欧美在线视频| 成人黄色片网站| 色综合视频一区中文字幕| 国产婷婷97碰碰久久人人蜜臀| 国产精品白丝av嫩草影院| 欧洲中文字幕国产精品| 日韩免费不卡av| 91国产美女在线观看| 欧美日韩国产综合新一区| 精品国产一区二区在线| 九九视频直播综合网| 91av网站在线播放| 成人午夜激情免费视频| 精品呦交小u女在线| 国产精品视频公开费视频| 91久久精品国产91久久性色| 国产精品444| 国产精品第100页| 91精品久久久久久久久中文字幕| 欧美日韩亚洲一区二| 九九久久久久99精品| 97在线视频免费观看| 日本午夜精品理论片a级appf发布| 国产精品久久久久久搜索| 日韩av电影在线免费播放| 美日韩精品视频免费看| 国产欧美亚洲精品| 热久久这里只有| 91福利视频网| 91老司机在线| 日韩最新中文字幕电影免费看| 国产精品高潮呻吟久久av黑人| 亚洲欧美中文在线视频| 亚洲精品视频播放| 国产精品jizz在线观看麻豆| 91免费精品视频| 92版电视剧仙鹤神针在线观看| 亚洲欧洲日产国产网站| 欧美一区二区大胆人体摄影专业网站| 亚洲成年人在线| 中文字幕日韩精品在线| 日本伊人精品一区二区三区介绍| 国产一区二区激情| 亚洲国产99精品国自产| 亚洲一区二区国产| 日韩av大片免费看| 久久露脸国产精品| 亚洲福利影片在线| 国产精品视频最多的网站| 在线观看欧美www| 丝袜亚洲欧美日韩综合| 一本一本久久a久久精品牛牛影视| 91在线精品视频| 欧美黄色三级网站| 国产91对白在线播放| 久久国内精品一国内精品| 中文字幕欧美国内| 91亚洲国产成人精品性色| 欧美整片在线观看| x99av成人免费| 一区二区三区四区在线观看视频| 中文字幕精品www乱入免费视频| 国产精品白嫩美女在线观看| 国产综合在线视频| 97视频在线免费观看| 在线精品91av| 亚洲电影中文字幕| 日本中文字幕久久看| 国产亚洲在线播放| 91禁外国网站| 亚洲国产欧美一区二区三区久久| 日韩欧美国产网站| 国产一区二区日韩精品欧美精品| 日本久久久久久久| 狠狠久久亚洲欧美专区| 成人网在线免费看| 国产成人精品一区二区在线| 欧美精品videosex极品1| 国产日韩精品综合网站| 亚洲淫片在线视频| 亚洲自拍小视频免费观看| 亚洲一区第一页| 亚洲自拍小视频| 亚洲风情亚aⅴ在线发布| 国产精品av网站| 91国偷自产一区二区三区的观看方式| 久久久之久亚州精品露出| 欧美多人爱爱视频网站| 亚洲香蕉av在线一区二区三区| 久久噜噜噜精品国产亚洲综合| 日韩久久精品电影| 欧美国产激情18| 欧美国产中文字幕| 亚洲一区二区三区sesese| 日韩一中文字幕| 国产精品99一区| 国产精品影片在线观看| 欧美成人第一页| 欧美激情精品久久久久久蜜臀| 国产精品人成电影| 国内成人精品一区| 国内精品视频一区| 国产精品中文字幕久久久| 精品福利在线观看| 亚洲三级黄色在线观看| 欧美多人乱p欧美4p久久| 日韩免费av片在线观看| 亚洲一级黄色片| 最近2019免费中文字幕视频三| 国产一区二区三区在线观看网站| 在线观看免费高清视频97| 欧美日韩国产一区二区三区| 国产啪精品视频| 欧美大片网站在线观看| 日本伊人精品一区二区三区介绍| 国产成人黄色av| 国产丝袜精品视频| 91超碰caoporn97人人| 一本一道久久a久久精品逆3p| 精品爽片免费看久久| 日韩精品亚洲视频| 欧美天天综合色影久久精品| 亚洲国产成人精品久久| 欧洲中文字幕国产精品| 亚洲风情亚aⅴ在线发布| 激情成人中文字幕| 中文字幕视频在线免费欧美日韩综合在线看| 91午夜理伦私人影院| 国产精品久久视频| 国产日本欧美一区二区三区在线| 欧美高清在线视频观看不卡| 亚洲精品videossex少妇| 日韩欧美在线中文字幕| 亚洲精品久久久久久久久久久久久| 精品久久久中文| 一区二区三区四区视频| 亚洲精品国产精品国自产观看浪潮| 成人中文字幕+乱码+中文字幕| 精品久久久久久亚洲精品| 日韩欧美国产免费播放| 亚州欧美日韩中文视频| 亚洲第一区第一页| 国产在线视频2019最新视频| 91视频国产高清|