最近問了大佬一個問題,監聽和定時器兩個效能的問題,大佬給我普及了巨集任務和微任務的概念,於是網上找見了這樣一段程式碼:
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0);
Promise.resolve().then(function() {
console.log('promise1');
}).then(function() {
console.log('promise2');});
console.log('script end');
複製程式碼
輸出:script start, script end, promise1, promise2, setTimeout
於是撤出了JavaScript的執行機制,JavaScript的事件迴圈、同步、非同步就不多說了,今天分享的是巨集任務和微任務。
先記住兩個概念:
宿主環境提供的叫巨集任務,由語言標準提供的叫微任務,這是算比較標準也算比較好記憶的區分巨集任務和微任務了。
宿主環境:
簡單來說就是能使javascript完美執行的環境,只要能完美執行javascript的載體就是javascript的宿主環境。目前我們常見的兩種宿主環境有瀏覽器和node。
我們都知道window是我們一直使用的全域性物件,但其實global 是 javascript 執行時所在宿主環境提供的全域性物件,在node出生前這個物件一直都存在於概念裡。直到node的出現才使我們真正看到了global。
global 是 javascript 執行時所在宿主環境提供的全域性物件,在瀏覽器中,沒有實現global物件,而是通過window物件來指向global物件,代替global成為全域性物件。因為瀏覽器暴露了一系列操作 DOM, Location, History 等 Api 供 javascript 呼叫,而這些操作物件在global中是不存在的。對於node來說,它不需要DOM這些操作,用到的只是javascript的原聲功能。
宿主環境內所有的內建或自定義的變數/函式都是 global/window 這個全域性物件的屬性/方法,而由宿主環境提供的也叫巨集任務。
語言標準:
我們都知道JavaScript是一種程式語言,但其實JavaScript由ECMA制定標準,稱之為ECMAScript,所以由語言標準提供的就是微任務,比如ES6提供的promise。
所以迴歸上面的程式碼,promise是ES6語言標準提供的,定時器是宿主環境提供的,所以promise會比定時器更早執行。
當然,不同瀏覽器不同環境對於這兩個的概念會有不同,相同的程式碼在不同瀏覽器執行會有不同的順序,在不同瀏覽器也會有不同的順序。想要深入研究的可以自行查一查資料。