調用堆棧

初衷:

無心之中發現一個很不錯的項目:中文地址原版英文地址,恰好適合本身鞏固加深理解JavaScript,因而定下一個小目標:總共33個知識點,天天攻克一個,一個月後再來回首感悟!javascript

後來(通過一天的實踐後)就被啪啪打臉了,因爲這個小目標是在空閒時間完成的,在兼顧自己工做的時候,天天更新一個知識點,現變成兩天一個吧。java

內容:

1.js是一個單線程的編程語言

意味着js在同一時間段內只能作一件事情,意味着它只有一個調用堆棧(call stack)。爲何呢?由於js是瀏覽器腳本語言,主要用來處理與用戶進行的操做、操做DOM之類的事情,若是它有多個線程,好比線程A想添加DOM節點,線程B想刪除該DOM節點,那它該何去何從呢?git

2.Event Loop(事件循環)

優秀的這篇文章
上圖來自於優秀的這篇文章github

同步任務和異步任務分別進入不一樣的「場所」。同步進入主線程,異步進入Event Table並註冊回調函數,而後將其移入進Event Queue中。主線程內的任務執行完畢直至爲空後,再去Event Queue讀取對應的函數,進入主線程。面試

上述過程不斷重複,就是Event Loop(事件循環)編程

3.宏任務(macro tasks)和微任務(micro tasks)

  • js中有兩類任務隊列:宏任務(macro tasks)和微任務(micro tasks).
    • 宏任務:script(全局任務)、setTimeout、setInterval、setImmediate、I/O、UI rendering
    • 微任務:process.nextTick、Promise, Object.observer, MutationObserver

4.一些面試題

setTimeout(_ => console.log(4))

new Promise(resolve => {
  resolve()
  console.log(1);
}).then(_ => {
  console.log(3);
})

console.log(2);
  • setTimeout屬於宏任務,new Promise屬於同步任務,因而直接輸出1
  • 後面的.then()加入微任務中,接下來直接輸出2
  • 微任務.then()比setTimeout先執行,故輸出3
  • 最後輸出4
●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);
  • 執行結果:一、四、七、五、二、三、6
● 執行全局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 start、script end、 promise一、 promise二、setTimeout
● 全局Script任務,直接輸出:script start、script end
    
    ● 接下來執行微任務,輸出promise一、promise2
    
    ● 最後輸出setTimeout
    
    ● 全部微任務總會在下一個宏任務以前所有執行完畢

結語:

看了好多篇優秀的文章,瞬間感受本身以前得有多**,多學習優秀者的優秀!今年開始,文章先發表在了掘金主頁了喲,所以博客園就滯後點了~瀏覽器

懵***

相關文章
相關標籤/搜索