線程與進程:前端
進程是系統資源分配和調度的單元。一個運行着的程序就對應一個進程。在windows中,每個打開的運行的應用程序或後臺程序,好比運行中的qq,谷歌瀏覽器,網易雲音樂,資源管理器等都是一個進程。一個進程包括了運行中的程序和程序所使用到的內存和系統資源。好比,邊聽音樂,邊在博客園寫博客,這 就是開了兩個進程。ajax
線程是進程下的執行者,一個進程至少會開啓一個線程(主線程),也能夠開啓多個線程。好比網易雲一遍播放音樂,一遍顯示歌詞,網易雲是進程,播放音樂和展現歌詞是網易雲進程下的兩個線程。windows
同步和異步:瀏覽器
同步異步是指程序的行爲。同步時程序發出調用的時候,一直等待直到返回結果。沒有結果以前不會返回。也就是說,同步是調用者主動等待調用的過程。多線程
異步是發出調用以後,立刻返回,可是不會立刻返回結果。調用者沒必要主動等待,當被調用者獲得結果以後會主動通知調用者。異步
上面的概念可能比較官方,不易理解。通俗來講,就是,你去賣煎餅,而後再那等老闆作好以後遞給你,你才能走的過程 就是同步。你去肯德基點餐,而後點完以後,找個位置坐着玩手機,等作好後以後,前臺的小哥哥小姐姐的叫號通知你去拿的過程就是異步。同步就是 只能一件件的事情去作,作完一件,再作一件。而異步不是,異步是你再作一件事的等待過程當中,能夠去作其餘的事情。這就是同步和異步的區分。函數
console.log(1) console.log('同步') console.log(2) //1 //同步 //2
console.log(1) setTimeout(() => {console.log('異步‘)}, 0) console.log(2) //1 //2 //異步
瀏覽器是單線程仍是多線程?---多線程spa
一個瀏覽器一般有如下幾個常駐的線程:線程
- 渲染引擎線程:顧名思義,該線程負責頁面的渲染。code
- JS引擎: 負責JS的解析和執行
- 定時觸發器線程: 處理定時事件,好比setTimeout,setInterval
- 事件觸發線程:處理DOM事件
- 異步http請求線程:處理http請求
瀏覽器只分配給Js一個主線程,用來執行任務,可是一次只能執行一個任務,這些任務造成一個任務隊列排隊等候執行,可是,前端的某些任務是很消耗時間的,若是,讓他們和別的任務同樣,都老老實實的排隊等待執行,執行效率就會很是的低,甚至致使頁面的假死。因此,瀏覽器爲了這些耗時任務,就開闢了另外的線程,如: http請求,瀏覽器定時觸發器等,這些任務 都是異步的,
那js 的單線程和異步 是否是有點自相矛盾呢?單線程和異步確實不能同時爲一個語言的特性,js 選擇了成爲單線程語言,因此它自己不多是異步的,但Js的宿主瀏覽器,Node等是多線程的,宿主環境經過某種方式使得Js具有了異步的屬性。
任務隊列
js任務分爲同步任務和異步任務,同步任務指的是,在主線程上排隊執行的任務,只有錢一個任務執行完畢,才能執行後一個任務。異步任務:不進入主線程,而進入「任務對列」的任務,只有「任務隊列」通知主線程,某個異步任務能夠執行了。該任務纔會進入主線程執行。
異步執行的運行機制:
- 全部的同步任務都在主線程上,造成一個【執行棧】
- 主線程以外,還存在一個「任務隊列」。只要異步任務有了運行結果,就在「任務隊列」之中放置一個事件。
- 一旦「執行棧」種的全部同步任務執行完畢,系統就會讀取「任務隊列」,看看裏面有哪些事件,那些對應的異步任務,因而結束等待狀態,進入執行棧,開始執行。
- 主線程不斷重複上面的第三步。
回調函數
當主線程開始執行異步任務,就是執行對應的回調函數。
異步任務必須指定回調函數。
js中的異步之定時器
setTimeout(function(){ console.log(0); },0) console.log(1);
//1
//0
當有耗時任務的時候,會把它放在任務隊列中等待主線程空閒而後再執行。實際再執行的過程當中,瀏覽器會默認setTimeout以及ajax請求這一類的方法都是耗時程序(儘管可能不耗時)。因此此時的setTimeout儘管它推遲時間爲0,可是js不會當即執行,而是把它加入任務隊列,當執行完執行棧的同步任務也就是打印1後,再執行setTimeout的回調函數,打印0。
setTimeout(fn,0)的含義是,指定某個任務在主線程最先可得的空閒時間執行。劃重點::: 儘早可能。也就是說setTimeout 將當前的回調函數加入到任務隊列中,當前任務耗時過長,須要等好久,滅有辦法保證,回調函數會在指定的時間內執行。