ES6/7 異步編程學習筆記
前言
在ES6的異步函數出現之前,Js實現異步編程只有settimeout、事件監聽、回調函數等幾種方法
settTmeout
這種方法常用於定時器與動畫的功能,因為其本質上其實是瀏覽器的WebAPIs功能,因此與主線程並不同,當延時方法到達觸發條件時,方法被添加到用於回調的任務隊列,只要執行引擎棧中的代碼執行完畢,主線程就會去讀取任務隊列,依次執行那些滿足觸發條件的回調函數。所以其等待時間在某些情況下往往不是那麽準備,這一方面推薦可以看看《你不知道的js》這方面的章節。
事件監聽
這一個方法其實在以jq為例的框架中比較常見,例如:a.on(‘click‘,function(){...})
優點:比較容易理解,可以綁定多個事件,每個事件可以指定多個回調函數,而且可以”去耦合”,有利於實現模塊化。
缺點:整個程序都要變成事件驅動型,運行流程會變得很不清晰。
回調函數
所謂回調函數,就是把任務的第二段單獨寫在一個函數裏面,等到重新執行這個任務的時候,就直接調用這個函數。
其實回調函數本身並沒有什麽問題,存在問題的是在很多情況下可能需要許多的回調函數去嵌套,這個時候就是所說的“回調地獄”
ES6/7: Promise、Generator、async/await
我對於Promise的認識就是將回調函數進行了優化以及封裝,把回調嵌套的情況解決了,使用了鏈式代替,並增加了狀態的管理,通過狀態傳遞來保證回調的正確引用。簡單舉個栗子:
fun1() .then(function(data){ console.log(data); return fun2(); }) .then(function(data){ console.log(data); return fun3(); }) .then(function(data){ console.log(data); });
其中fun1,fun2,fun3三個函數都定義為Promise對象
generator最大的不同是會控制函數的執行和暫停,栗子為使用generator實現斐波那契數列:
function * fibonacci() { let [prev, curr]= [1, 0]; for (;;) { [prev, curr] = [curr, prev + curr]; yield curr; } } for (let n of fibonacci()) { if (n > 1000) break; console.log(n); }
async/await則是generator的一個語法糖,將其進行了封裝
同樣實現一個斐波那契數列:
var fi = async function() { var t, a = 0, b = 1, n = 0; while (n < 10) { await a; [a, b] = [b, a + b]; n ++; console.log(a) } return; }
可以看出,與generator相比,async/await的優點在於1.有其內置的執行器。2.有著更好的語意性。3.其適用性更強:yield 命令後面只能是 Thunk 函數或 Promise 對象,而 async 函數的 await 命令後面,可以跟 Promise 對象和原始類型的值
ES6/7 異步編程學習筆記