js中同步異步,任務隊列

單線程

  • 瀏覽器是多線程運行的,它給js分配一個線程;js就是單線程運行的【一次只幹一件事】

所謂單線程,就是隻一次只能完成一件任務。若是有多個任務,就必須排隊,前面一個任務完成,在執行後面一個任務,以次類推。javascript

js執行分爲同步和異步,其中異步來自於瀏覽器提供的異步隊列,在瀏覽器中分爲兩個任務隊列,一個是主任務隊列【同步編程】,一個是等待任務隊列【異步編程】java

瞭解js的異步咱們應該先了解下js的運行環境=>瀏覽器

一個瀏覽器一般由一下幾個常住的線程編程

  • 渲染引擎線程:顧名思義,該線程負責頁面的渲染
  • js引擎線程:負責js解析和執行
  • 定時觸發器線程:處理定時事件,好比setTimeout,setInterval
  • 事件觸發線程:處理DOM事件
  • 異步http請求線程:處理http請求

注意:渲染線程和js引擎線程是不能同時進行的。渲染線程在執行任務的時候,js引擎線程會被掛起。由於js能夠操做DOM,若在渲染中js處理了DOM,瀏覽器可能就不知所措了瀏覽器

雖然JavaScript是單線程的,但是瀏覽器內部不是單線程的。一些I/O操做、定時器的計時和事件監聽(click, keydown...)等都是由瀏覽器提供的其餘線程來完成的。服務器

Javascript語言將任務的執行模式分紅兩種:同步(Synchronous)和異步(Asynchronous)。

"同步模式"就是上一段的模式,後一個任務等待前一個任務結束,而後再執行,程序的執行順序與任務的排列順序是一致的、同步的;"異步模式"則徹底不一樣,每個任務有一個或多個回調函數(callback),前一個任務結束後,不是執行後一個任務,而是執行回調函數,後一個任務則是不等前一個任務結束就執行,因此程序的執行順序與任務的排列順序是不一致的、異步的。多線程

"異步模式"很是重要。在瀏覽器端,耗時很長的操做都應該異步執行,避免瀏覽器失去響應,最好的例子就是Ajax操做。在服務器端,"異步模式"甚至是惟一的模式,由於執行環境是單線程的,若是容許同步執行全部http請求,服務器性能會急劇降低,很快就會失去響應。異步

同步

console.log(1)
    function fn(){
        console.log(2)
    }
    fn()
    console.log(3)

上面代碼輸入1 2 3 ,由於js是單線程的,代碼由上而下依次執行async

異步

js中異步編程

  • AJax請求
  • 定時器
  • 事件
  • 回調函數函數

    上面這4中都是屬於異步的

console.log(1)
    setTimeout(()=>{
        console.log(2)
    })
    console.log(3)

上面代碼執行會輸出,1 3 2 ,由於setTimeout是異步的,js會將setTimeout放到異步隊列,等待同步隊列所有執行完畢,在執行異步隊列

任務隊列

js中有兩類任務隊列:宏任務隊列和微任務隊列。宏任務隊列能夠有多個,微任務隊列只有一個

  • 宏任務:script(全局任務),setTimeout,setInterval
  • 微任務:process.nextTick, Promise, Object.observer
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

相關文章
相關標籤/搜索