【視頻資源已上架嗶哩嗶哩,關注up主波羅丁的菠蘿】node
hello你們好,本次分享一下關於JavaScript執行機制的知識點。那麼廢話很少說,直接上結論,首先咱們知道JavaScript是一門單線程語言,決定JavaScript執行順序的並非代碼順序,而是event loop順序。promise
咱們先來說解一下什麼是同步任務,什麼是異步任務。同步任務就是按照代碼寫的順序一步一步執行下去,而異步代碼呢,會先將要執行的代碼放入異步隊列裏,而後執行同步代碼,等同步代碼所有執行完畢以後,再去異步隊列裏去查看是否有待執行的代碼,若是有的話,就會執行。瀏覽器
用setTimeout演示一下異步
setTimeout(()=>{ console.log('timeout'); },0); console.log('11111');
咱們先不看執行結果是什麼,先把這段代碼的event loop順序安排一下oop
// 首先進入總體代碼 // 接着遇到了setTimout,執行它,把它對應的方法放到異步隊列裏去,等0ms以後再來執行它 // 接着走,遇到了console.log('11111');執行它,輸出1111 // ok同步的執行完了,我去異步隊列瞅瞅還有啥 // 異步隊列 // 發現了console.log('timeout');,ok執行它就完了 console.log('timeout');
注意一下setTimeout第二個參數,等0ms以後再執行它,0ms以後須要看同步任務是否已經執行完畢,若是同步任務還在執行,那麼只好繼續等下去直到同步任務執行完畢線程
好比code
// 1000ms後執行 setTimeout(()=>{ console.log('timeout'); },1000); alert('同步阻塞');
拿着去瀏覽器裏執行一下,會發現只要我不點按鈕一直讓同步任務阻塞住它就不輸出timeout視頻
接下來咱們再說一下Promise隊列
let p = new Promise((resolve,reject)=>{ console.log('promise'); resolve(); }); p.then(()=>{ console.log('resolve'); }); console.log('同步');
咱們先不看執行結果是什麼,先把這段代碼的event loop順序安排一下ip
// 首先進入總體代碼 // 接着遇到了new Promise,執行它,輸出console.log('promise') // 接着走,遇到了promise的then;執行它,把它對應的代碼放到異步隊列裏 // 接着走,遇到了console.log('同步');執行它,輸出同步 // ok同步的執行完了,我去異步隊列瞅瞅還有啥 // 異步隊列 // 發現了console.log('resolve');,ok執行它就完了,輸出resolve console.log('resolve');
那麼Promise和setTimeout有什麼不一樣呢,看着都同樣啊,我們也不磨嘰直接上結論,在JavaScript除了同步任務和異步任務外,也能夠按照宏任務和微任務來區分。宏任務包括總體代碼,setTimeout,setInterval,而微任務包括Promise,process.nextTick。process.nextTick是node環境下的咱們暫且不說它。宏任務產生的異步代碼會放到下次event loop中,而微任務產生的代碼會放到本次event loop的末尾處。咱們來用一段代碼來演示
// 異步-宏任務 setTimeout(()=>{console.log('timeout')},0); // 同步 let p = new Promise((resolve,reject)=>{ console.log('promise'); resolve(); }); // 異步-微任務 p.then(()=>{ console.log('resolve'); }); // 同步-宏任務 console.log('同步');
那麼這個輸出的結果是怎樣的的呢,咱們再來分析一下,此次已是第三次手把手分析代碼了,明白什麼意思嗎?
// 首先進入總體代碼 // 接着遇到了setTimout,執行它,把它對應的方法放到異步隊列【宏任務】裏去,等0ms以後再來執行它 // 接着遇到了new Promise,執行它,輸出console.log('promise') // 接着走,遇到了promise的then;執行它,把它對應的代碼放到異步隊列【微任務】裏 // 接着走,遇到了console.log('同步');執行它,輸出同步 // ok同步的執行完了,我去異步隊列瞅瞅還有啥 // 異步隊列 // 【Promise微任務】本次event loop console.log('resolve'); // 【setTimeout宏任務】下一次event loop console.log('timeout')