關於JS中同步和異步的一點說明

  你們可能都知道,JS語言的執行環境是單線程的。node

所謂單線程就是指一次只能完成一件任務,若是有多個任務,就必須排隊,等前面一個任務執行完成,再執行後面一個任務,依次進行。ajax

好處:實現起來比較簡單,執行環境相對單純。瀏覽器

缺點:只要存在一個任務耗時好久,後面的任務都必須排隊等着,會拖延整個程序的執行。常見的瀏覽器無響應(假死)每每就是由於某一段JS代碼長時間運行(好比死循環),致使整個頁面卡在某個任務,其它任務沒法執行。多線程

那麼爲了解決這個問題。JS將任務的執行模式分爲兩種:同步(synchronous) 和 異步(asynchronous)。異步

同步上面已經介紹過,即後一個任務等前一個任務結束後再執行,程序的執行順序與任務的排列順序是一致的、同步的。async

異步模式則徹底不一樣,每個任務有一個多多個回調函數(callback),前一個任務結束後,不是執行後一個任務,而是執行回調函數,後一個任務則是不等前一個任務結束就執行,因此程序的執行順序與任務的排列順序不是一致的。函數

異步模式很是重要。在瀏覽器端,耗時很長的操做都應該是異步執行,避免瀏覽器失去響應,最好的列子就是ajax操做。oop

異步調用不會阻止代碼的順序執行,而是在未來的某一個時刻觸發設置好的邏輯,因此咱們:spa

1.並不知道邏輯何時會被調用;線程

2.只能定義當觸發的時候邏輯是什麼;

3.只能等待,同時能夠去處理其餘的邏輯;

setTimeout就是這樣的一個異步調用。

var a = 1;
function f1(a){
console.log("I am in f1");
setTimeout(function(){a+=2;console.log("f1:" + a);},1000)}
f1(a);
console.log("out:" + a);

 

獲得的結果以下圖所示:

I am in f1
out:1
f1:3

結果代表代碼執行過程當中確實是先執行了f1函數,在執行console.log輸出後,setTimeout的回調函數在執行過程當中被掛起,知道1s後才被調用,在等待執行setTImeout回調函數的時間裏,JS選擇執行後面的任務,即執行了console.log("out:" + a);

實際上,異步函數,如setTimeout和setInterval,是被壓入了稱之爲Event Loop的隊列。

Event Loop是一個回調函數隊列。當異步函數執行時,回調函數會被壓入這個隊列。JavaScript引擎直到異步函數執行完成後,纔會開始處理事件循環。這意味着JavaScript代碼不是多線程的,即便表現的行爲類似。事件循環是一個先進先出(FIFO)隊列,這說明回調是按照它們被加入隊列的順序執行的。JavaScript被 node選作爲開發語言,就是由於寫這樣的代碼多麼簡單啊。

相關文章
相關標籤/搜索