單線程,同步異步,阻塞非阻塞的理解


一.概念理解

1.同步異步:

同步和異步關注的是消息通信機制 (synchronous communication/ asynchronous communication)所謂同步,就是在發出一個*調用*時,在沒有得到結果之前,該*調用*就不返回。但是一旦調用返回,就得到返回值了。換句話說,就是由*調用者*主動等待這個*調用*的結果。

而異步則是相反,*調用*在發出之后,這個調用就直接返回了,所以沒有返回結果。換句話說,當一個異步過程調用發出后,調用者不會立刻得到結果。而是在*調用*發出后,*被調用者*通過狀態、通知來通知調用者,或通過回調函數處理這個調用。

2.阻塞非阻塞:

阻塞和非阻塞關注的是程序在等待調用結果(消息,返回值)時的狀態.

阻塞調用是指調用結果返回之前,當前線程會被掛起。調用線程只有在得到結果之后才會返回。
非阻塞調用指在不能立刻得到結果之前,該調用不會阻塞當前線程。

作者:嚴肅
鏈接:https://www.zhihu.com/question/19732473/answer/20851256
來源:知乎

3.單線程:

我們常說“JavaScript是單線程的”。

所謂單線程,是指在JS引擎中負責解釋和執行JavaScript代碼的線程只有一個。不妨叫它主線程。

但是實際上還存在其他的線程。例如:處理AJAX請求的線程、處理DOM事件的線程、定時器線程、讀寫文件的線程(例如在Node.js中)等等。這些線程可能存在於JS引擎之內,也可能存在於JS引擎之外,在此我們不做區分。不妨叫它們工作線程。

 

二.JS中的同步異步理解:

1.同步:

Math.sqrt(2);
console.log('Hi');
第一個函數返回時,就拿到了預期的返回值:2的平方根。
第二個函數返回時,就看到了預期的效果:在控制台打印了一個字符串

2異步:(以異步函數setTimeout為例)

setTimeout(function(){console.log("a")}, 500);
console.log("b");
//"b"
//"a"
setTimeout函數返回時,並不能立即得到結果,而是先運行后面的程序,等到被調用函數通知時(500ms以后通知),再運行。

3.異步過程的構成要素:

  主線程發起一個異步請求,相應的工作線程接收請求並告知主線程已收到(異步函數返回);主線程可以繼續執行后面的代碼,同時工作線程執行異步任務;工作線程完成工作后,通知主線程;主線程收到通知后,執行一定的動作(調用回調函數)。

  所以,從主線程的角度看,一個異步過程包括下面兩個要素:

  • 發起函數(或叫注冊函數)

  • 回調函數callbackFn 

4.消息隊列與事件循環:
工作線程將消息放到消息隊列,主線程通過事件循環過程去取消息。消息就是注冊異步任務時添加的回調函數。

  • 消息隊列:消息隊列是一個先進先出的隊列,它里面存放着各種消息。

  • 事件循環:事件循環是指主線程重復從消息隊列中取消息、執行的過程。

作者:manxisuo

鏈接:https://segmentfault.com/a/1190000004322358

 

三.JS中異步編程的幾種方式

1.回調函數:

假設有函數

f1();
f2();
f2必須在f1完成后運行,f1又是一個耗時的應用

 

 則可使用異步調用:

 
         

function f1(f2){
    setTimeout(function () {
      console.log("a")
      // f1的任務代碼
      f2()}, 1000)}
function f2(){console.log("b")};
f1(f2);
console.log("c");}

//"c"

//"a"

//"b"

這樣,就把同步操作變成了異步操作;

 

2.事件監聽:采用事件驅動模式。任務的執行不取決於代碼的順序,而取決於某個事件是否發生。

 

還是以f1和f2為例。首先,為f1綁定一個事件(這里采用的jQuery的寫法)。
  f1.on('done', f2);
上面這行代碼的意思是,當f1發生done事件,就執行f2。然后,對f1進行改寫:
  function f1(){
    setTimeout(function () {
      // f1的任務代碼
      f1.trigger('done');
    }, 1000);
  }
f1.trigger('done')表示,執行完成后,立即觸發done事件,從而開始執行f2。

 

3.發布、訂閱:

4.Promise對象:

Promises對象是CommonJS工作組提出的一種規范,目的是為異步編程提供統一接口。簡單說,它的思想是,每一個異步任務返回一個Promise對象,該對象有一個then方法,允許指定回調函數。比如,f1的回調函數f2,可以寫成:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM