JavaScript異步編程的6種方式

衆所周知 JavaScript 是單線程(single thread)工作,也就是隻有一個腳本執行完成後才能執行下一個腳本,兩個腳本不能同時執行,如果某個腳本耗時很長,後面的腳本都必須排隊等着,會拖延整個程序的執行。那麼如何讓程序像人類一樣可以多線程工作呢?

如果這條馬路只有一個車道,那麼五菱神車就可能會被法拉利擋住,如果是多車道(多線程)或者......,對吧?

  • 回調函數
  • 事件監聽
  • 發佈訂閱模式
  • Promise
  • Generator(ES6)
  • async(ES7) 

JavaScript異步編程基本的解決方案:回調函數事件監聽

示例:假設有兩個函數, f1 和 f2,f1 是一個需要一定時間的函數。

function f1() {
    setTimeout(function () {
        console.log('先執行 f1')
      }, 2000)
  }
  function f2() {
      console.log('再執行 f2')
  }

回調函數

因爲 f1 是一個需要2s時間的函數,所以可以將 f2 寫成 f1 的 回調函數,將同步操作變成異步操作,f1 不會阻塞程序的運行,f2 也無需空空等待,例如 JQuery 的 ajax。

function f1(f2){
    setTimeout(function (){
        console.log('先執行 f1')
      }, 1000);
      f2()
  }
  function f2(){
    console.log('再執行 f2')
  }
  f1(f2);

回調執行結果:

總結:回調函數的優點是簡單、易於實現、便於理解,缺點是不利於代碼的閱讀和維護,多次回調會導致代碼高度耦合(Coupling),流程會很混亂,而且每個任務只能指定一個回調函數。

事件監聽

另一種思路是腳本的執行不取決代碼的順序,而取決於某個事件是否發生。採用事件驅動模式。

f1.on('done', f2);
//當f1發生done事件,就執行f2。然後,對f1進行改寫:
function f1(){

    setTimeout(function () {

      // f1的任務代碼

      f1.trigger('done');

    }, 1000);

  }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章