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

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

淺談Javascript線程及定時(shí)機(jī)制

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

setTimeout、setInterval的使用

  Javascript api文檔中定義setTimeout和setInterval第二個(gè)參數(shù)意義分別為間隔多少毫秒后回調(diào)函數(shù)被執(zhí)行和每隔多少毫秒回調(diào)函數(shù)被執(zhí)行。但隨著工作經(jīng)驗(yàn)的積累,我們發(fā)現(xiàn)事實(shí)并非如此。

  比如

div.onclick=function(){  setTimeout(function(){     document.getElementById('input').focus();   },0);}

就解釋不通了,立即執(zhí)行就立即執(zhí)行唄,干嘛還要設(shè)置個(gè)定時(shí)兜個(gè)圈子呢。

  又有一天你寫(xiě)了下面一段代碼

setTimeout(function(){while(true){}},100);setTimeout(function(){alert('你好');},200);

第一行代碼死循環(huán),結(jié)果造成第二行alert始終沒(méi)有出現(xiàn),為啥哩?

單線程or多線程?
  原來(lái),Javascript引擎是單線程運(yùn)行的,瀏覽器只有一個(gè)線程在運(yùn)行JavaScript程序。因?yàn)閱尉€程的設(shè)計(jì),所以免去了復(fù)雜的多線程同步問(wèn)題。

  當(dāng)設(shè)置一個(gè)定時(shí)的時(shí)候,瀏覽器會(huì)在設(shè)定的時(shí)間后將你指定的回調(diào)函數(shù)插入任務(wù)序列,而非立即執(zhí)行。如果設(shè)定定時(shí)時(shí)間為0,表示立即插入任務(wù)序列,而不是立即執(zhí)行,仍然要等隊(duì)列中任務(wù)執(zhí)行完畢,輪到你,你才執(zhí)行。

  所以下面代碼先彈出2,再?gòu)棾?

setTimeout(function(){  alert(1);},0);alert(2);

  那么,這又有什么實(shí)際用途呢?且看下面示例

<!DOCTYPE html><html>  <head>    <meta charset="utf-8">    <meta name="viewport" content="width=device-width,initial-scale=1.0">    <title>setTimeout 0</title>  </head>  <body>    輸入字符,但內(nèi)容卻不能實(shí)時(shí)顯示<input type="text" onkeydown="show(this.value)"/> <br/>    輸入字符,內(nèi)容能實(shí)時(shí)顯示<input type="text" onkeydown="var self=this;setTimeout(function(){show(self.value)},0)"/>    <div></div>    <script>      function show(val){        document.getElementsByTagName("div")[0].innerHTML=val;      }    </script>  </body></html>

  這個(gè)例子中,js引擎需要執(zhí)行keydown事件處理程序,然后更新輸入框的value值。事件處理程序執(zhí)行時(shí),更新value的任務(wù)只能進(jìn)入隊(duì)列等待,所以keydown事件執(zhí)行時(shí)無(wú)法得到更新后的value值;但通過(guò)setTimeout我們把取value的操作放入隊(duì)列,并在更新value之后執(zhí)行,所以內(nèi)容就能實(shí)時(shí)顯示了。

  再回來(lái)看看下面的代碼:

setTimeout(function(){  //do something...   setTimeout(arguments.callee,10);},10);setInterval(function(){  //do something...},10);

      這兩段代碼看起來(lái)效果一樣,是不是。其實(shí)還是有區(qū)別的,第一段的回調(diào)函數(shù)內(nèi)的setTimeout是js引擎執(zhí)行后再設(shè)定的新的定時(shí),假定從上一個(gè)回調(diào)處理完到下一個(gè)回調(diào)開(kāi)始為一個(gè)時(shí)間間隔,理論上時(shí)間間隔>=10ms,后一段代碼<=10ms。

  說(shuō)到這兒,那XMLHttpRequest是不是真的異步呢?是的,請(qǐng)求是異步的,不過(guò)這請(qǐng)求是瀏覽器新開(kāi)的一個(gè)線程。當(dāng)請(qǐng)求的狀態(tài)變更時(shí),如果先前已設(shè)置回調(diào),異步線程就將狀態(tài)變更事件放入js引擎處理隊(duì)列中等待處理,當(dāng)任務(wù)被處理時(shí)js引擎始終還是單線程地執(zhí)行onreadystatechange所設(shè)置的函數(shù)的。

以上所述就是本文的全部?jī)?nèi)容了,希望大家能夠喜歡。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 宜都市| 孝昌县| 德安县| 鄢陵县| 固镇县| 台前县| 伊金霍洛旗| 惠东县| 鸡东县| 兰考县| 抚松县| 易门县| 莱阳市| 安化县| 铜梁县| 苗栗县| 新余市| 隆化县| 黑山县| 吉木萨尔县| 分宜县| 利辛县| 河津市| 赣榆县| 呼伦贝尔市| 西畴县| 连云港市| 兖州市| 宜兴市| 济南市| 盘锦市| 都江堰市| 镇康县| 堆龙德庆县| 定结县| 望江县| 沁阳市| 松江区| 甘孜县| 茌平县| 冕宁县|