Recently, I came across a requirement where I had to call a function repeatedly after specific time interval, like sending ajax call at every 10 seconds. Sure, best option seems as setInterval, but it blew up my face like a cracker :)
In order to understand why setInterval is evil we need to keep in mind a fact that javascript is essentially single threaded, meaning it will not perform more than one operation at a time.
In cases when functions takes longer than delay mentioned in setInterval (like ajax call, which might it prevent from completing on time), we will find that either functions have no breathing room or setInterval breaks it"s rhythm.
var fakeCallToServer = function() { setTimeout(function() { console.log("returning from server", new Date().toLocaleTimeString()); }, 4000); } setInterval(function(){ let insideSetInterval = new Date().toLocaleTimeString(); console.log("insideSetInterval", insideSetInterval); fakeCallToServer(); }, 2000); //insideSetInterval 14:13:47 //insideSetInterval 14:13:49 //insideSetInterval 14:13:51 //returning from server 14:13:51 //insideSetInterval 14:13:53 //returning from server 14:13:53 //insideSetInterval 14:13:55 //returning from server 14:13:55
Try above code snippets in your console
As you can see from printed console.log statement that setInterval keeps on sending ajax calls relentlessly without caring previous call has returned or not.
This can queue up a lot of requests at once on the server.
Now, let"s try a synchronous operation in setInterval:
var counter = 0; var fakeTimeIntensiveOperation = function() { for(var i =0; i< 50000000; i++) { document.getElementById("random"); } let insideTimeTakingFunction = new Date().toLocaleTimeString(); console.log("insideTimeTakingFunction", insideTimeTakingFunction); } var timer = setInterval(function(){ let insideSetInterval = new Date().toLocaleTimeString(); console.log("insideSetInterval", insideSetInterval); counter++; if(counter == 1){ fakeTimeIntensiveOperation(); } if (counter >= 5) { clearInterval(timer); } }, 1000); //insideSetInterval 13:50:53 //insideTimeTakingFunction 13:50:55 //insideSetInterval 13:50:55 <---- not called after 1s //insideSetInterval 13:50:56 //insideSetInterval 13:50:57 //insideSetInterval 13:50:58
We see here when setInterval encounters time intensive operation, it does either of two things, a) try to get on track or b) create new rhythm. Here on chrome it creates a new rhythm.
Conclusion
In case of asynchronous operations, setTimeInterval will create long queue of requests which will be very counterproductive.
In case of time intensive synchronous operations, setTimeInterval may break the rhythm.
Also, if any error occurs in setInterval code block, it will not stop execution but keeps on running faulty code. Not to mention they need a clearInterval function to stop it.
Alternatively, you can use setTimeout recursively in case of time sensitive operations.
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/106524.html
摘要:按照定時(shí)器的時(shí)間間隔,處第二個(gè)函數(shù)加入到事件隊(duì)列,但此時(shí)正在執(zhí)行,所以只能等待。這樣做的好處是,在前一個(gè)定時(shí)器代碼執(zhí)行完之前,不會(huì)向隊(duì)列插入新的定時(shí)器代碼,確保不會(huì)有任何缺失的間隔。 JavaScript高級(jí)程序設(shè)計(jì)(第三版)(以下簡稱紅寶書)22.3高級(jí)定時(shí)器中詳細(xì)介紹了定時(shí)器setTimeout和setInterval,看完書后,深入理解了二者的區(qū)別,結(jié)合前輩們給我的建議用setT...
摘要:但我認(rèn)為談不上的毛病,而是編程模型和之間的一種模式差異。相比類,更貼近編程模型,使得這種差異更加突出。聲明本文采用循序漸進(jìn)的示例來解釋問題。本文假設(shè)讀者已經(jīng)使用超過一個(gè)小時(shí)。這是通過組件生命周期上綁定與的組合完成的。 本文由云+社區(qū)發(fā)表作者:Dan Abramov 接觸 React Hooks 一定時(shí)間的你,也許會(huì)碰到一個(gè)神奇的問題: setInterval 用起來沒你想的簡單。 R...
摘要:更方便的在于,由于自帶定時(shí)器功能,我們甚至不用自己去維護(hù)一個(gè)時(shí)間戳。請(qǐng)注意這里由于沒有調(diào)用另一個(gè)腳本,我們通過和的方式將我們的定時(shí)器程序傳入中。 問題 經(jīng)常使用Javascript的同學(xué)一定對(duì)setInterval非常熟悉,當(dāng)使用setInterval(callback, timer)時(shí),每經(jīng)過timer毫秒時(shí)間,系統(tǒng)都將調(diào)用一次callback。請(qǐng)問全局如果沒有提供setInterv...
摘要:這里是結(jié)論,將是更驚艷的那一個(gè)。瀏覽器隔一段時(shí)間像服務(wù)器發(fā)送一個(gè)請(qǐng)求,詢問這里有沒有需要更新的消息。在響應(yīng)回來時(shí),才會(huì)繼續(xù)發(fā)出第二個(gè)請(qǐng)求。但是,顯然的,這對(duì)我們要做的事來說并不算是什么問題。 我們都知道的是setTimout是用來延遲一個(gè)簡單的動(dòng)作的,然而,setInterval的目的是用來重復(fù)執(zhí)行某個(gè)動(dòng)作的。 然后,以上只是一半的事實(shí)。因?yàn)槿绻粋€(gè)函數(shù)需要在一個(gè)間隔時(shí)間內(nèi)重復(fù)的執(zhí)行,...
摘要:而寫成還可以滿足你獲得回調(diào)函數(shù)返回值的需求。而構(gòu)建函數(shù)表達(dá)式的方法也不止把聲明括起來這種,一些其他的操作符也可以,比如賦值號(hào)到目前為止,我們似乎能夠得出結(jié)論函數(shù)聲明后不可直接跟圓括號(hào),而函數(shù)表達(dá)式后面可以。 使用setTimeout替代setInterval setInterval()這個(gè)間歇調(diào)用函數(shù)是應(yīng)用得比較廣的,尤其在比較古老的瀏覽器中實(shí)現(xiàn)動(dòng)畫效果時(shí),往往離不開它。然而這個(gè)函數(shù)卻...
閱讀 3659·2021-10-09 09:58
閱讀 1202·2021-09-22 15:20
閱讀 2503·2019-08-30 15:54
閱讀 3520·2019-08-30 14:08
閱讀 897·2019-08-30 13:06
閱讀 1827·2019-08-26 12:16
閱讀 2687·2019-08-26 12:11
閱讀 2517·2019-08-26 10:38