摘要:工作線程執(zhí)行異步任務,執(zhí)行完成后把對應額回調(diào)函數(shù)封裝成一條消息放到消息隊列中主線程不斷地從消息隊列中取消息并執(zhí)行。當消息隊列為空時,主線程阻塞,直到消息隊列再次非空。取決于何時被主線程的事件循環(huán)取到,并執(zhí)行。
轉(zhuǎn)自:http://palmer.arkstack.cn/201...
一:平時簡單使用
1.setTimeout延遲一段時間執(zhí)行一次(only one)
setTimeout(function, milliseconds, param1, param2, ...) clearTimeout() // 阻止定時器運行 setTimeout(function(){ alert("Hello"); }, 3000); // 3s后彈出
2.setInterval 每隔一段時間執(zhí)行一次 (Many times)
setInterval(function, milliseconds, param1, param2, ...) e.g. setInterval(function(){ alert("Hello"); }, 3000); // 每隔3s彈出
3.setTimeout和setInterval的延時最小間隔是4ms;在JavaScript中沒有任何代碼是立刻執(zhí)行的,但一旦進程空閑就盡快執(zhí)行。所以 setTimeout 還是setInterval,設置的時間都是n毫秒被添加到隊列中,而不是過n毫秒后立即執(zhí)行。
二:進程與線程
1.模擬一個場景
有一個大型工廠
工廠有若干車間,每次只能有一個車間作業(yè)
每個車間 有若干工人在流水線作業(yè)
那么:
一個工廠對應的就是計算機的一個cpu,平時講的多核就代表多個工廠
每個工廠里的車間就是進程,意味著同一時刻一個cpu只運行一個進程,其余進程怠工
這個運行的車間(進程)里的工人,就是線程,可以有多個工人(線程)
車間(進程)里的房間,代表內(nèi)存
在深入一點:
車間(進程)里工人可以隨意在多個房間(內(nèi)存)之間走動,意味著一個進程里,多個線程可以共享內(nèi)存
部分房間(內(nèi)存)有限,只允許一個工人(線程)使用,此時其他工人(線程)要等待
房間里有工人進去后上鎖,其他工人需要等房間(內(nèi)存)里的工人(線程)開鎖出來后,才能進去,這就是互斥鎖
再深入:
如果同時有多個車間作業(yè),就是多進程
如果一個車間里有多個工人協(xié)同作業(yè),就是多線程
當然不同車間之間的工人也可以有互相協(xié)作,就需要協(xié)調(diào)機制
三:JavaScript單線程
JavaScript這門語言的核心特征,就是單線程(是指在JS引擎中負責解釋和執(zhí)行JavaScript代碼的線程只有一個)。這和JavaScript最初設計是作為一門GUI變成語言有關,最初用于瀏覽器端,單一線程控制GUI是很普遍的做法。雖然JavaScript是單線程,當瀏覽器是多線程的!!!!!!!例如webkit或是Gecko引擎,可能有JavaScript引擎線程,界面渲染線程,瀏覽器事件觸發(fā)線程,Http請求線程,讀寫文件的線程。
四:同步異步
1.同步(synchronous):假如一個函數(shù)返回時,調(diào)用者就能夠得到預期結(jié)果(即拿到了預期的返回值或者看到了預期的效果)這就是同步函數(shù)
e.g. alert("馬上能看到我拉"); console.log("也能馬上看到我哦");
2.異步(asynchronous):假如一個函數(shù)返回時,調(diào)用者不能得到預期結(jié)果,需要通過一定手段才能獲得,這就是異步函數(shù)。
e.g. setTimeout(function() { // 過一段時間才能執(zhí)行我哦 }, 1000);
五:異步構成要素
一個異步過程通常是這樣的:主線程發(fā)起一個異步請求,相應的工作線程(比如瀏覽器的其他線程)接受請求并告知主線程已收到(異步函數(shù)返回);主線程可以繼續(xù)執(zhí)行 后面代碼,同時工作線程執(zhí)行異步任務,工作線程完成工作號,告知主線程;主線程收到通知后,執(zhí)行一定的動作(調(diào)用回調(diào)函數(shù))
六:通信機制
異步過程的通信機制:工作線程將消息放到消息隊列,主線程通過事件循環(huán)過程去取消息
七:事件循環(huán)Event Loop
主線程(js線程)只會做一件事,就是從消息隊列里面取消息,執(zhí)行消息,再取消息,再執(zhí)行。消息隊列為空時,就會等待直到消息隊列變成非空。只有當前的消息執(zhí)行結(jié)束,才會去取下一個消息。這種機制就叫做事件循環(huán)機制Event Loop,取一個消息并執(zhí)行的過程叫做一次循環(huán)
工作線程是生產(chǎn)者,主線程是消費者。工作線程執(zhí)行異步任務,執(zhí)行完成后把對應額回調(diào)函數(shù)封裝成一條消息放到消息隊列中;主線程不斷地從消息隊列中取消息并執(zhí)行。當消息隊列為空時,主線程阻塞,直到消息隊列再次非空。
八:setTimeOut(function,0)發(fā)生了什么
setTimeOut的function的任務異步執(zhí)行,0不代表立即執(zhí)行,而是將任務推到消息隊列的最后,再由主線程的事件循環(huán)調(diào)用。
setTimeOut的最小時間不是0ms而是4ms
九:setInterval缺點
定時器指定的時間間隔,表示的是何時將定時器的代碼添加到消息隊列,而不是何時執(zhí)行代碼,所以真正何時執(zhí)行代碼的時間是不能保證的。取決于何時被主線程的事件循環(huán)取到,并執(zhí)行。
setInterval(function, N)
上面代碼意味著,每隔N秒把function事件推到消息隊列中,什么時候執(zhí)行,就不知道了
上圖可見,setInterval每隔100ms往隊列中添加一個事件;100ms后,添加T1定時器代碼至隊列中,主線程中還有任務在執(zhí)行,所以等待,some event執(zhí)行結(jié)束后執(zhí)行T1定時器代碼;又過了100ms,T2定時器被添加到隊列中,主線程還在執(zhí)行T1代碼,所以等待;又過了100ms,理論上又要往隊列里推一個定時器代碼,但由于此時T2還在隊列中,所以T3不會被添加,結(jié)果就是此時被跳過;這里我們可以看到,T1定時器執(zhí)行結(jié)束后馬上執(zhí)行了T2代碼,所以并沒有達到定時器的效果。
setInterval兩個缺點:
使用setInterval時,某些間隔會被跳過
可能多個定時器會連續(xù)執(zhí)行
十:鏈式setTimeOut
setTimeout(function () { // 任務 setTimeout(arguments.callee, interval); }, interval)
在嚴格模式下,第5版ECMAScript(ES5)禁止使用arguments.callee()。當一個函數(shù)必須調(diào)用自身的時候,避免使用arguments.callee(),通過要么給函數(shù)表達式一個名字,要么使用一個函數(shù)聲明
上述函數(shù)每次執(zhí)行的時候都會創(chuàng)建一個新的定時器,第二個setTimeOut使用了arguments.callee()獲取當前函數(shù)的引用,并且為其設置另一個定時器。在一個定時器執(zhí)行完前,不會向隊列插入新的定時器(解決缺點一),保證定時器間隔(解決缺點二)
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/94538.html
摘要:注意如果主邏輯的代碼執(zhí)行時間已經(jīng)超過了第二個參數(shù)設置的時間,那么等運行到該回調(diào)函數(shù)時,它會忽略掉這個時間,并立即執(zhí)行。如果某一個進行大量的計算,那么它就會阻塞在當前的回調(diào)函數(shù)中,等待該計算完成后,再執(zhí)行下一個的回調(diào)函數(shù)。 setTimeout() ? JavaScript是一個單線程的語言,也就是說它同一時間只能執(zhí)行一段代碼,接下來我們通過兩個例子說明一下單線程語言和多線程語言的...
摘要:關于定時器的源碼在文件中,進入就關于定時器的一些設計解釋,因為是做服務端代碼,在內(nèi)部等大部分事件都會創(chuàng)建一個定時器,任何時間都可能存在大量的定時器任務,所以設計一個高效的定時器是很有必要的。 博客文章地址 setTimeout與setInterval setTimeout 和 setInterval 是我們在 javaScript 中經(jīng)常用到的定時器,setTimeout 方法用于...
摘要:看一下例子一些其他的代碼假定處理程序需要執(zhí)行,這時雖然在添加了定時器代碼,但是仍舊需要等待事件完成后才能夠執(zhí)行。缺點某些間隔會被跳過多個定時器的代碼執(zhí)行之間的間隔可能會比預期小。 一. setTimeout 1. 定義 window.setTimeout(func,[delay,param1,param2,····]); window.setTimeout(code,[delay]);...
摘要:定時器方法相關方法有四種。返回值返回值是一個正整數(shù),表示定時器的編號。這個值可以傳遞給來取消該定時器。使用方法很簡單只有一個參數(shù),該參數(shù)為您要取消定時器的標識符。用法很簡單當代碼運行到這行的時候,會取消所設置的定時器。 簡單介紹在JavaScript中定時器有兩個 setInterval() 與 setTime...
摘要:第二個調(diào)用當前執(zhí)行的函數(shù),并為其設置另外一個定時器。使得在前一個定時器代碼執(zhí)行完之前,不會向隊列插入新的定時器代碼,確保不會有任何缺失的間隔。 在自己用canvas畫一個時鐘時,畫秒鐘用的是利用圖片將重復的線條遮住,但是會出現(xiàn)有兩個秒鐘線條同時存在,才想起setInterval有那么個坑,查了點資料,記錄下,若有不對的或者未寫到的點,還請大家指出,謝謝^_^ 在此之前先科普下這個學習點...
閱讀 785·2023-04-26 00:30
閱讀 2689·2021-11-23 09:51
閱讀 1045·2021-11-02 14:38
閱讀 2559·2021-09-07 10:23
閱讀 2243·2021-08-21 14:09
閱讀 1362·2019-08-30 10:57
閱讀 1603·2019-08-29 11:20
閱讀 1149·2019-08-26 13:53