国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > JavaScript > 正文

setTimeout函數(shù)的神奇使用

2019-11-19 17:25:05
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

【寫(xiě)在前面的胡言亂語(yǔ)】

  自從大三開(kāi)始實(shí)習(xí)之后,就沒(méi)有寫(xiě)博客了,雖然學(xué)了很多東西,但是如果沒(méi)有進(jìn)行總結(jié)和分享,學(xué)的東西就很容易忘記,而且不進(jìn)行分享,就不會(huì)手動(dòng)去敲代碼,這樣對(duì)知識(shí)的理解就不夠透徹。

現(xiàn)在畢業(yè)半年多了,最近學(xué)習(xí)了《JavaScript高級(jí)程序設(shè)計(jì)》這本書(shū),受益匪淺,看了才知道雖然自己寫(xiě)了那么多JS,但是對(duì)JS的理解最多就只是中下水平。

現(xiàn)在看第二遍,邊看邊敲代碼,邊分享,希望看到這篇文章的你,能有所收獲。

【這是正文】

  《JavaScript高級(jí)程序設(shè)計(jì)》這本書(shū)里面,介紹了很多關(guān)于setTimeout函數(shù)的神奇使用,今天來(lái)介紹下第一個(gè)――使用setTimeout代替setInterval進(jìn)行間歇調(diào)用。

  書(shū)中是這么說(shuō)的

“在開(kāi)發(fā)環(huán)境下,很少使用間歇調(diào)用(setInterval),原因是后一個(gè)間歇調(diào)用很可能在前一個(gè)間歇調(diào)用結(jié)束前啟動(dòng)”。

  這話怎么理解呢?

  首先我們來(lái)看一下一般情況下的setInterval函數(shù)的使用,以及如何使用setTimeout代替setInterval

var executeTimes = 0;var intervalTime = 500;var intervalId = null; // 放開(kāi)下面的注釋運(yùn)行setInterval的DemointervalId = setInterval(intervalFun,intervalTime);// 放開(kāi)下面的注釋運(yùn)行setTimeout的Demo// setTimeout(timeOutFun,intervalTime); function intervalFun(){executeTimes++;console.log("doIntervalFun――"+executeTimes);if(executeTimes==5){clearInterval(intervalId);}} function timeOutFun(){executeTimes++;console.log("doTimeOutFun――"+executeTimes);if(executeTimes<5){setTimeout(arguments.callee,intervalTime);}}

  代碼比較簡(jiǎn)單,我們只是在setTimeout的方法里面又調(diào)用了一次setTimeout,就可以達(dá)到間歇調(diào)用的目的。

  重點(diǎn)來(lái)了,為什么作者建議我們使用setTimeout代替setInterval呢?setTimeout式的間歇調(diào)用和傳統(tǒng)的setInterval間歇調(diào)用有什么區(qū)別呢?

  區(qū)別在于,setInterval間歇調(diào)用,是在前一個(gè)方法執(zhí)行前,就開(kāi)始計(jì)時(shí),比如間歇時(shí)間是500ms,那么不管那時(shí)候前一個(gè)方法是否已經(jīng)執(zhí)行完畢,都會(huì)把后一個(gè)方法放入執(zhí)行的序列中。這時(shí)候就會(huì)發(fā)生一個(gè)問(wèn)題,假如前一個(gè)方法的執(zhí)行時(shí)間超過(guò)500ms,加入是1000ms,那么就意味著,前一個(gè)方法執(zhí)行結(jié)束后,后一個(gè)方法馬上就會(huì)執(zhí)行,因?yàn)榇藭r(shí)間歇時(shí)間已經(jīng)超過(guò)500ms了。

  書(shū)中沒(méi)有給出代碼證明這個(gè)結(jié)論,于是自己寫(xiě)了一段代碼來(lái)驗(yàn)證。

var executeTimes = 0;var intervalTime = 500;var intervalId = null;var oriTime = new Date().getTime(); // 放開(kāi)下面的注釋運(yùn)行setInterval的DemointervalId = setInterval(intervalFun,intervalTime);// 放開(kāi)下面的注釋運(yùn)行setTimeout的Demo// setTimeout(timeOutFun,intervalTime); function intervalFun(){executeTimes++;var nowExecuteTimes = executeTimes;var timeDiff = new Date().getTime() - oriTime;console.log("doIntervalFun――"+nowExecuteTimes+", after " + timeDiff + "ms");var delayParam = 0;sleep(1000);console.log("doIntervalFun――"+nowExecuteTimes+" finish !");if(executeTimes==5){clearInterval(intervalId);}} function timeOutFun(){executeTimes++;var nowExecuteTimes = executeTimes;var timeDiff = new Date().getTime() - oriTime;console.log("doTimeOutFun――"+nowExecuteTimes+", after " + timeDiff + "ms");var delayParam = 0;sleep(1000);console.log("doTimeOutFun――"+nowExecuteTimes+" finish !");if(executeTimes<5){setTimeout(arguments.callee,intervalTime);}} function sleep(sleepTime){var start=new Date().getTime();while(true){  if(new Date().getTime()-start>sleepTime){  break;}}}

  (這里使用大牛提供的sleep函數(shù)來(lái)模擬函數(shù)運(yùn)行的時(shí)間)

  執(zhí)行setInterval的Demo方法,看控制臺(tái)

  可以發(fā)現(xiàn),fun2和fun1開(kāi)始的間歇接近1000ms,剛好就是fun1的執(zhí)行時(shí)間,也就意味著fun1執(zhí)行完后fun2馬上就執(zhí)行了,和我們間歇調(diào)用的初衷背道而馳。

  我們注釋掉setInterval的Demo方法,放開(kāi)setTimeout的Demo方法,運(yùn)行,查看控制臺(tái)

  這下終于正常了,fun1和fun2相差了1500ms = 1000 + 500,fun2在fun1執(zhí)行完的500ms后執(zhí)行。

  不知道你有沒(méi)有和我一樣腦洞大開(kāi),反正我是感覺(jué)視野又開(kāi)闊了一點(diǎn),setTimeout的妙用還有很多,下次接著聊!

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 邵阳市| 韩城市| 上饶市| 广水市| 城固县| 临邑县| 蒲城县| 宁南县| 绥江县| 黎城县| 乌兰县| 丹阳市| 邢台县| 兰溪市| 炉霍县| 聊城市| 许昌县| 疏附县| 马尔康县| 连云港市| 抚松县| 葫芦岛市| 高唐县| 襄垣县| 新田县| 巴楚县| 大关县| 于都县| 威远县| 孙吴县| 定边县| 汉川市| 柘荣县| 陕西省| 广饶县| 高碑店市| 浙江省| 琼结县| 河南省| 临夏县| 渭源县|