一、js的內存模型
二、js代碼執行機制:
-
-
主線程之外,還存在一個"任務隊列"(task queue)。只要異步任務有了運行結果,就在"任務隊列"之中放置一個事件。
-
三、宏任務與微任務:
-
-
MicroTask(微觀任務) process.nextTick, Promise, Object.observe, MutationObserver
-
案例一:(在主線程上添加宏任務)
先看代碼:一個打印,一個定時器,一個打印
因為定時器是異步操作,又是宏任務,所以先執行第一個打印,接着將setTimeout放入宏任務隊列,接着執行第二個打印,再執行宏任務隊列中的setTimeout
案例二:(在主線程上添加微任務)
console.log(1) new Promise(function(resolve,reject){ console.log('2') resolve() }).then(function(){ console.log(3) }) console.log(4) //1 2 4 3
先看代碼:一個打印,一個new promise,一個promise.then,一個打印
因為new promise會立即執行,promise.then是異步操作且是微任務
所以,先執行第一個打印,執行new Promise,將promise.then放入微任務隊列,接着執行第二個打印,再執行微任務隊列中的promise.then
案例三:(紅任務中創建微任務)
console.log('1'); setTimeout(function () { console.log('2'); new Promise(function (resolve) { console.log('3'); resolve(); }).then(function () { console.log('4') }) },0) new Promise(function (resolve) { console.log('5'); resolve(); }).then(function () { console.log('6') }) setTimeout(function () { console.log('7'); new Promise(function (resolve) { console.log('8'); resolve(); }).then(function () { console.log('9') }) console.log('10') },0) console.log('11')
先看代碼:一個打印,第一個定時器,一個new promise,一個promise.then,第二個定時器,一個打印
定時器是異步操作,又是宏任務,promise.then是異步操作且是微任務
所以,先執行第一個打印(1),將第一個定時器放入宏任務隊列,執行new Promise(5),將promise.then放入微任務隊列,將第二個定時器放入宏任務隊列,執行打印(11);
主線程上的代碼執行完畢后,看是否有微任務?此時:微任務隊列中有一個promise.then,執行它(6);微任務執行完畢看宏任務隊列;
此時宏任務隊列中兩個定時器,延時都是0秒,所以按順序執行就ok,先執行第一個定時器
第一個定時器中:一個打印,一個mew promise,一個promise.then(微任務);(宏任務中包含微任務,一定要將宏任務中的微任務執行完,再去執行下一個宏任務)
先執行打印(2),再執行new promise(3),再執行promise.then(4);第一個宏任務執行完,執行第二個宏任務(第二個定時器)
第二個定時器中:一個打印,一個new promise,一個promise.then(微任務),一個打印
先執行第一個打印(7),再執行new promise(8),再執行第二個打印(10),在執行promise.then(9)
案例四:(微任務中創建宏任務)
new Promise((resolve) => { console.log("1") resolve() }).then(() => { console.log("2") setTimeout(() => { console.log("3") },0) }) setTimeout(() => { console.log("4") },1000) console.log("5") //1 5 2 3 4
先看代碼:一個new promise,(一個then,一個定時器(0秒)),一個定時器(1秒),一個打印 微任務中有宏任務,則將宏任務放入宏任務隊列任務中
先執行new promise(1),再將promise.then放入微任務隊列,將定時器放入宏任務隊列(0秒),將定時器放入宏任務隊列(1秒),執行打印(5)
接着看微任務隊列,執行promise.then(2);微任務隊列中都執行完再看宏任務隊列
宏任務隊列中兩個定時器,一個延時0秒,一個延時1秒,所以先執行延時0秒的那個
第一個定時器:執行(3);
第二個定時器:執行(4)