首先瀏覽器是多線程的,JS是單線程的(瀏覽器只給js分配了一個線程)
單線程的特點就是一次只能處理一件事情。(后一個任務需要等待前一個任務的執行,這就可能出現長時間的等待)
JS在單線程中實現異步機制主要依賴瀏覽器的任務隊列
任務隊列分為主任務隊列,等待任務隊列
在主任務隊列自上而下執行的時候,如果遇到一個異步操作任務,不會立即執行而是把它放到等待任務隊列中去排隊
當主任務隊列完成后才會到等待任務隊列中進行查找(主任務隊列完不成,不管等待任務隊列是否到達時間,都不做處理,會繼續等待主任務隊列完成)
等待任務隊列中的內容,先達到條件的會被重新放到主任務隊列中執行,然后接着去等待任務隊列中查找
這就是因為js是單線程的。只能處理一件事情~~
單線程就意味着,所有任務需要排隊,前一個任務結束,才會執行后一個任務。如果前一個任務耗時很長,后一個任務就不得不一直等待
同步:在一個線程上同一個時間只能做一件事情。當前事情完成才能進行下一個任務
異步:在主棧中執行一個任務,但是發現這個任務是一個異步的操作,會把它移除主棧放到等待任務隊列中
異步編程里面又分為宏任務和微任務
宏任務有定時器、事件綁定、ajax、回調函數、node中fs模塊
微任務有promise、async await、process.nextTick
執行順序:先執行主任務,執行完接着執行微任務,最后執行宏任務,按照條件的順序依次執行。
這種循環機制又叫事件循環(event loop)
栗子:
async function as1(){ console.log('as1 start'); await as2(); console.log('as1 end'); } async function as2(){ console.log('as2'); } console.log('script start'); setTimeout(function(){ console.log('setTimeout'); },0) as1(); new Promise(function(resolve){ console.log('prom1'); resolve(); }).then(function(){ console.log('prom2'); }); console.log('script end'); //script start => as1 start => as2 => prom1 => script end //=> as1 start => prom2 => setTimeout