JavaScript的單線程
Javascript最大的特點就是他的單線程執行,作為瀏覽器腳本語言,Javascript的主要用途是於用戶互動,以及操作DOM,這決定了它只能是單線程,假如javaScript是多線程,一個線程在DOM節點上添加內容,而另一個線程卻刪除了該節點,這時瀏覽器因該以哪個線程為准?因此,為了避免復雜性,JavaScript就采用了單線程的工作模式。
JavaScript的結構分析
單線程就意味着它只有一條運行線路,也就是一次只能做一件事情,那么,問題就來了,如果是CPU一直在工作,那也就罷了,但是如果CPU處於空閑狀態,而且等待的事務對接下來的任務沒有影響,這就浪費了大量的資源。例如:獲取網絡上的信息,線程一直等到信息獲取完成再執行,在此之前都處於等待狀態就太浪費了。於是JavaScript就引人了同步異步機制。
同步任務:下一個任務受上一個任務所影響,即需要上一個任務執行完之后才能執行下一個任務。
異步任務:異步任務就是不進入主線程,而進入“任務隊列”,(並不是立即執行),等到可以執行了,任務隊列會通知主線程:某個異步任務可以執行了。該任務才會被主線程調用執行。(回調函數、定時器函數、用戶點擊事件等)
運行方式:所有同步任務進入主線程隊列執行,所有異步任務進入任務隊列,主線程先執行完所有同步任務,再調用可執行的異步任務。(主線程空閑的時候才會調用執行異步任務)。任務隊列是一個先進先出的數據結構,排在前面的事件優先被主線程讀取。主線程調用時會先檢查時間,因為存在定時器函數,這類函數只有滿足規定的時間才會被調用。
Event Loop
因為主線程從任務隊列中讀取事件的這個過程是不斷循環的,因此又被稱為Event Loop(事件循環)。
Node.js的process.nextTick 和 setImmediate.
process.nextTick=(func) 在當前執行棧的尾部執行。setImmediate(func)在任務隊列的尾部。
也就是說nextTick會在當前func執行完成后立即執行func里新加的任務,而setImmediate需要按隊列順序執行到func里增加的任務
JavaScript的call(),bind().apply();
call,bind,apply都是修改對象的this指針。
func.call():修改this指針並執行函數,參數為具體的參數。
func.bind():修改this指針但是不執行函數,返回的是函數名稱,參數為具體參數。
func.apply():修改this指針並執行函數,參數為參數數組。
eg: func(para1,para2)
func.call(obj,para1,para2)
func.apply(obj,[para1,para2])