所謂單線程,就是隻一次只能完成一件任務。若是有多個任務,就必須排隊,前面一個任務完成,在執行後面一個任務,以次類推。javascript
js執行分爲同步和異步,其中異步來自於瀏覽器提供的異步隊列,在瀏覽器中分爲兩個任務隊列,一個是主任務隊列【同步編程】,一個是等待任務隊列【異步編程】java
一個瀏覽器一般由一下幾個常住的線程編程
setTimeout
,setInterval
注意:渲染線程和js引擎線程是不能同時進行的。渲染線程在執行任務的時候,js引擎線程會被掛起。由於js能夠操做DOM,若在渲染中js處理了DOM,瀏覽器可能就不知所措了瀏覽器
雖然JavaScript是單線程的,但是瀏覽器內部不是單線程的。一些I/O操做、定時器的計時和事件監聽(click, keydown...)等都是由瀏覽器提供的其餘線程來完成的。服務器
"同步模式"就是上一段的模式,後一個任務等待前一個任務結束,而後再執行,程序的執行順序與任務的排列順序是一致的、同步的;"異步模式"則徹底不一樣,每個任務有一個或多個回調函數(callback),前一個任務結束後,不是執行後一個任務,而是執行回調函數,後一個任務則是不等前一個任務結束就執行,因此程序的執行順序與任務的排列順序是不一致的、異步的。多線程
"異步模式"很是重要。在瀏覽器端,耗時很長的操做都應該異步執行,避免瀏覽器失去響應,最好的例子就是Ajax操做。在服務器端,"異步模式"甚至是惟一的模式,由於執行環境是單線程的,若是容許同步執行全部http請求,服務器性能會急劇降低,很快就會失去響應。異步
console.log(1) function fn(){ console.log(2) } fn() console.log(3)
上面代碼輸入1 2 3 ,由於js是單線程的,代碼由上而下依次執行async
js中異步編程
回調函數函數
上面這4中都是屬於異步的
console.log(1) setTimeout(()=>{ console.log(2) }) console.log(3)
上面代碼執行會輸出,1 3 2 ,由於
setTimeout
是異步的,js會將setTimeout
放到異步隊列,等待同步隊列所有執行完畢,在執行異步隊列
js中有兩類任務隊列:宏任務隊列和微任務隊列。宏任務隊列能夠有多個,微任務隊列只有一個
setTimeout(_ => console.log(4)) new Promise(resolve => { resolve() console.log(1) }).then(_ => { console.log(3) }) console.log(2)
上面代碼中,setTimeout就是做爲宏任務來存在的,而Promise.then則是具備表明性的微任務
全部會進入的異步都是指的事件回調中的那部分代碼
也就是說
new Promise
在實例化的過程當中所執行的代碼都是同步進行的,而then
中註冊的回調纔是異步執行的。
在同步代碼執行完成後纔回去檢查是否有異步任務完成,並執行對應的回調,而微任務又會在宏任務以前執行。因此就獲得了上面的輸出1 2 3 4