無心之中發現一個很不錯的項目:中文地址、原版英文地址,恰好適合本身鞏固加深理解JavaScript,因而定下一個小目標:總共33個知識點,天天攻克一個,一個月後再來回首感悟!javascript
後來(通過一天的實踐後)就被啪啪打臉了,因爲這個小目標是在空閒時間完成的,在兼顧自己工做的時候,天天更新一個知識點,現變成兩天一個吧。java
意味着js在同一時間段內只能作一件事情,意味着它只有一個調用堆棧(call stack)。爲何呢?由於js是瀏覽器腳本語言,主要用來處理與用戶進行的操做、操做DOM之類的事情,若是它有多個線程,好比線程A想添加DOM節點,線程B想刪除該DOM節點,那它該何去何從呢?git
上圖來自於優秀的這篇文章github
同步任務和異步任務分別進入不一樣的「場所」。同步進入主線程,異步進入Event Table並註冊回調函數,而後將其移入進Event Queue中。主線程內的任務執行完畢直至爲空後,再去Event Queue讀取對應的函數,進入主線程。面試
上述過程不斷重複,就是Event Loop(事件循環)編程
setTimeout(_ => console.log(4)) new Promise(resolve => { resolve() console.log(1); }).then(_ => { console.log(3); }) console.log(2);
●setTimeout的做用是等待給定的時間後爲它的回調產生一個新的宏任務; ●Promise.then則是具備表明性的微任務; ●new Promise在實例化的過程當中所執行的代碼都是同步進行的,而then中註冊的回調纔是異步執行的; ●同步代碼執行完成後纔回去檢查是否有異步任務完成,並執行對應的回調,而微任務又會在宏任務以前執行
setTimeout(function(){ console.log('定時器開始啦') }); new Promise(function(resolve){ console.log('立刻執行for循環啦'); for(var i = 0; i < 10000; i++){ i == 99 && resolve(); } }).then(function(){ console.log('執行then函數啦') }); console.log('代碼執行結束');
執行結果:立刻執行for循環啦,代碼執行結束,執行then函數啦, 定時器開始啦。(解析步驟同上!)
***promise
console.log(1); setTimeout(() => { console.log(2); Promise.resolve().then(() => { console.log(3) }); }); new Promise((resolve, reject) => { console.log(4) resolve(5) }).then((data) => { console.log(data); }) setTimeout(() => { console.log(6); }) console.log(7);
● 執行全局Script,直接輸出1,後面的setTimeout爲宏任務; ● new Promise至關於同步任務,輸出4,後面的.then()加入到微任務隊列中,後面的setTimeout爲宏任務; ● 接着執行全局Script,直接輸出7; ● 執行完全部的宏任務後,接着在微任務隊列中的全部,輸出5; ● 接着執行剩下的宏任務,輸出2; ● 而後執行上一步宏任務後產生的微任務,輸出3; ● 最後執行最後一個setTimeout宏任務,輸出6;
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任務,直接輸出:script start、script end ● 接下來執行微任務,輸出promise一、promise2 ● 最後輸出setTimeout ● 全部微任務總會在下一個宏任務以前所有執行完畢
看了好多篇優秀的文章,瞬間感受本身以前得有多**,多學習優秀者的優秀!今年開始,文章先發表在了掘金主頁了喲,所以博客園就滯後點了~瀏覽器