JavaScript學(xué)習(xí)筆記整理_setTimeout的應(yīng)用
setTimeou的t應(yīng)用
var ids = [];
function foo1(i) {
this.i = i;
console.log('i = '+i);
ids[0] = setTimeout((function () {
foo1(i);
}),1000);
}
function foo2(j) {
this.j = j;
console.log('j = '+j);
ids[1] = setTimeout((function () {
foo2(j);
}),1000);
}
foo1(2);
foo2(3);
clearTimeout(ids[0]);
clearTimeout(ids[1]);
當(dāng) setTimeout(f,n) 被調(diào)用時(shí),它會(huì)返回一個(gè) ID 標(biāo)識(shí)并且計(jì)劃在將來大約n毫秒后調(diào)用f函數(shù)。 f函數(shù)只會(huì)被執(zhí)行一次(遞歸執(zhí)行的話就可以實(shí)現(xiàn)每n毫秒執(zhí)行一次),基于 JavaScript 引擎的計(jì)時(shí)策略,以及本質(zhì)上的單線程運(yùn)行方式,所以其它代碼的運(yùn)行可能會(huì)阻塞此線程。 因此沒法確保函數(shù)會(huì)在 setTimeout 指定的時(shí)刻被調(diào)用。通過在回調(diào)函數(shù)內(nèi)部使用 setTimeout 函數(shù)來防止阻塞!
JavaScript 是異步的,setTimeout 只會(huì)執(zhí)行回調(diào)函數(shù)一次,不過 setInterval會(huì)每隔 X 毫秒執(zhí)行函數(shù)一次。 但是卻不鼓勵(lì)使用這個(gè)函數(shù)。當(dāng)回調(diào)函數(shù)的執(zhí)行被阻塞時(shí),setInterval 仍然會(huì)發(fā)布更多的回調(diào)指令。在很小的定時(shí)間隔情況下,這會(huì)導(dǎo)致回調(diào)函數(shù)被堆積起來。
setTimeout 和 setInterval 也接受第一個(gè)參數(shù)為字符串的情況。 這個(gè)特性絕對(duì)不要使用,因?yàn)樗趦?nèi)部使用了隱藏的eval,由于 eval 在這種情況下不是被直接調(diào)用,因此傳遞到 setTimeout 的字符串會(huì)自全局作用域中執(zhí)行,建議不要在調(diào)用定時(shí)器函數(shù)時(shí),為了向回調(diào)函數(shù)傳遞參數(shù)而使用字符串的形式;當(dāng)需要向回調(diào)函數(shù)傳遞參數(shù)時(shí),可以創(chuàng)建一個(gè)匿名函數(shù),在函數(shù)內(nèi)執(zhí)行真實(shí)的回調(diào)函數(shù);
onscolll,onresize等是非常耗性能,那如果我們換成ajax請(qǐng)求的話,那么就會(huì)縮放一次窗口會(huì)連續(xù)觸發(fā)多次ajax請(qǐng)求,下面我們?cè)囍褂煤瘮?shù)節(jié)流的操作試試一下;當(dāng)然加個(gè)settimeout()的定時(shí)器就好了,
第一種封裝方法
var count = 0;
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)
}, 200)
}
第二種封裝方法
構(gòu)造一個(gè)閉包,使用閉包的方式形成一個(gè)私有的作用域來存放定時(shí)器timer, timer是通過傳參數(shù)的形式引入的。
var count = 0;
function oCount() {
count++;
console.log(count);
}
var funs= delayFun(oCount,100);
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)
};
}
對(duì)第二種方法優(yōu)化一下,性能會(huì)更好
這里返回一個(gè)函數(shù),如果它被不間斷地調(diào)用,它將不會(huì)得到執(zhí)行。該函數(shù)在停止調(diào)用 N 毫秒后,再次調(diào)用它才會(huì)得到執(zhí)行。如果有傳遞 ‘immediate' 參數(shù),會(huì)馬上將函數(shù)安排到執(zhí)行隊(duì)列中,而不會(huì)延遲。
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() {
// 所有繁重的操作
}, 250);
window.addEventListener('resize', myEfficientFn);
函數(shù)不允許回調(diào)函數(shù)在指定時(shí)間內(nèi)執(zhí)行多于一次。當(dāng)為一個(gè)會(huì)頻繁觸發(fā)的事件分配一個(gè)回調(diào)函數(shù)時(shí),該函數(shù)顯得尤為重要。
setTimeout這么厲害,那么我們是可以在項(xiàng)目中大量使用嗎?
我個(gè)人是不建議的,在我們業(yè)務(wù)中,基本上是禁止在業(yè)務(wù)邏輯中使用setTimeout的,因?yàn)槲宜吹降暮芏嗍褂梅绞蕉际且恍﹩栴}不好解決,setTimeout作為一個(gè)hack的方式。
例如,當(dāng)一個(gè)實(shí)例還沒有初始化的前,我們就使用這個(gè)實(shí)例,錯(cuò)誤的解決辦法是使用實(shí)例時(shí)加個(gè)setTimeout,確保實(shí)例先初始化。
為什么錯(cuò)誤?這里其實(shí)就是使用hack的手段
第一是埋下了坑,打亂模塊的生命周期
第二是出現(xiàn)問題時(shí),setTimeout其實(shí)是很難調(diào)試的。
我認(rèn)為正確的使用方式是,看看生命周期(可參考《關(guān)于軟件的生命周期 》),把實(shí)例化提到使用前執(zhí)行
以上就是小編為大家?guī)淼腏avaScript學(xué)習(xí)筆記整理_setTimeout的應(yīng)用的全部?jī)?nèi)容了,希望對(duì)大家有所幫助,多多支持腳本之家~
- python實(shí)現(xiàn)JAVA源代碼從ANSI到UTF-8的批量轉(zhuǎn)換方法
- Javascript獲取圖片原始寬度和高度的方法詳解
- Java HttpURLConnection超時(shí)和IO異常處理
- Java Socket聊天室編程(二)之利用socket實(shí)現(xiàn)單聊聊天室
- java分割日期時(shí)間段代碼
- Java有效處理異常的三個(gè)原則
- Java 線程池詳解及實(shí)例代碼
- javabean servlet jsp實(shí)現(xiàn)分頁功能代碼解析
- JavaWeb Session 會(huì)話管理實(shí)例詳解
- JavaScript每天必學(xué)之事件
- Javascript中常見的邏輯題和解決方法
- Java socket字節(jié)流傳輸示例解析
- JDK的Parser來解析Java源代碼詳解
相關(guān)文章
深入理解JavaScript系列(36):設(shè)計(jì)模式之中介者模式詳解
這篇文章主要介紹了深入理解JavaScript系列(36):設(shè)計(jì)模式之中介者模式詳解,中介者模式(Mediator)是指用一個(gè)中介對(duì)象來封裝一系列的對(duì)象交互,需要的朋友可以參考下2015-03-03
對(duì)JavaScript客戶端應(yīng)用編程的一些建議
這篇文章主要介紹了對(duì)JavaScript客戶端應(yīng)用編程的一些建議,主要針對(duì)MVC框架框架的一些相關(guān)使用問題,需要的朋友可以參考下2015-06-06
JavaScript 創(chuàng)建運(yùn)動(dòng)框架的實(shí)現(xiàn)代碼
本篇文章是對(duì),在JavaScript中創(chuàng)建運(yùn)動(dòng)框架的實(shí)現(xiàn)方法進(jìn)行了介紹。需要的朋友參考下2013-05-05
JavaScript中用getDate()方法返回指定日期的教程
這篇文章主要介紹了JavaScript中用getDate()方法返回指定日期的教程,是JS入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-06-06
JavaScript對(duì)象學(xué)習(xí)經(jīng)驗(yàn)整理
主要包括對(duì)象的創(chuàng)建、對(duì)象屬性的設(shè)置和查詢、對(duì)象方法等等,整理如下,感興趣的朋友可以參考下2013-10-10
Javascript代碼在頁面加載時(shí)的執(zhí)行順序介紹
Javascript代碼在頁面加載時(shí)的執(zhí)行順序介紹,需要的朋友可以參考一下2013-05-05
Javascript數(shù)組循環(huán)遍歷之forEach詳解
本篇文章主要介紹了Javascript 數(shù)組循環(huán)遍歷之forEach詳解,對(duì)學(xué)習(xí)forEach有很好的幫助,有需要的可以了解一下。2016-11-11
document.getElementBy("id")與$("#id")有什么區(qū)
有朋友問document.getElementBy("id")與$("#id")的區(qū)別,其實(shí)第一個(gè)就是js中獲取對(duì)象的方法, 第二個(gè)是通過自定義函數(shù)方便調(diào)用,而第三個(gè)是jquery中獲取id對(duì)象的方法2013-09-09

