今天在學習koa2的時候發現本身對async的使用方法和原理都不是很熟悉,連帶着發現本身對前端異步的解決方案並瞭解並不如何深入,因此乾脆把前端現有的異步解決方案都複習了一遍。
今天先把將用callback和事件監聽思想解決異步問題的代碼貼出來,明天再補充代碼的解析及其餘解決方案;前端
function f1(f2) { setTimeout(function () { let b = 10; f2(b) }, 1000) } function f2(data) { console.log("callback_type_demo", data) } f1(f2);
這麼寫以後會於1s後再控制檯打出 callback_type_demo 10。該方式容易理解,實際上就是是在f1執行完以後再調用f2,可是這個方法在多個異步操做嵌套的時候就變得很是難受。好比說這樣:dom
function f1(f) { setTimeout(function () { let a = 10; setTimeout(function () { let b = a + 10; setTimeout(function () { let c = b + 10; setTimeout(function () { let d = c + 10; setTimeout(function () { let e = d + 10; f(e) }, 1000) }, 1000) }, 1000) }, 1000) }, 1000) } function finalF(data){ console.log('finalF',data) } f1(finalF);
代碼執行完以後會於5s後打印出 finalF 50,多層嵌套以後該方法的語義就會開始不清晰,不容易理解與維護,而且在實際狀況中,咱們還須要對藉口返回的錯誤進行處理,那麼這個寫法就變得愈發的混亂和複雜,因此該方法是不可取的;koa
如下是我對 能夠被監聽事件的對象DOM 的實現,不想了解具體實現方式的能夠跳過異步
//實現事件監聽 /* DOM 能夠被監聽事件的對象 .on("eventName",function) 第一個參數爲監聽的事件名,第二個參數爲 綁定 的方法 .removeOn("eventName",function) 第一個參數爲監聽的事件名,第二個參數爲 解綁 的方法 .trigger("eventName") 參數接收事件名,觸發該事件(並觸發該事件綁定的全部方法) */ //具體實現能夠不看,不影響對事件監聽解決異步的理解 let DOM = function () { //被監聽的事件的集合 let eventList = {}; //綁定事件監聽的方法 this.on = function (eventName, fun) { if (typeof eventName !== "string") { console.error("監聽的事件名應爲字符串"); return; } if (typeof fun !== "function") { console.error("被觸發的必須是事件"); return; } eventList[eventName] = eventList[eventName] || []; eventList[eventName].push(fun); }; //移除事件監聽的方法 this.removeOn = function (eventName, fun) { let onList = eventList[eventName]; if (onList) { for (let i = 0; i < onList.length; i++) { if (onList[i] === fun) { onList.splice(i, 1); return } } } }; //觸發事件監聽的方法 this.trigger = function (eventName, param) { let onList = eventList[eventName]; if (onList) { for (let i = 0; i < onList.length; i++) { onList[i](param) } } }; };
接下來的是利用事件監聽解決異步的方案,須要認真看的async
//生成兩個DOM實例 let dom1 = new DOM(); let dom2 = new DOM(); //異步模擬 let f2 = function () { setTimeout(function () { console.log("開始觸發事件:"); console.log("dom1 'done' 事件 觸發:"); dom1.trigger('done', 20); console.log("dom2 'done' 事件 觸發:"); dom2.trigger("done", "123"); }, 100); }; let f3 = function (data) { console.log("f3 run",data) }; //爲dom1,dom2的'done' 事件綁定 f3 方法 console.log("dom1 On f3"); dom1.on("done", f3); console.log("dom1 On f3"); dom2.on("done", f3); f2(); setTimeout(function () { console.log("dom1 removeOn f3"); dom1.removeOn("done", f3); f2(); }, 200);
這裏貼出該代碼的運行日誌
這裏能夠看到被綁定以後,第一次f2運行時,f3分別被dom1, dom2的'done'事件觸發了;
可是在dom1解綁了f3以後,f2再次運行時,f3就只被dom2的‘done’事件觸發了
事件監聽模式不用關心被綁定的函數何時執行,咱們只須要在特定的時候觸發對應的事件就能夠了。同時這個模式也程序至關的依賴事件,變成事件驅動,運行流程會變得很不清晰。函數
今天的文章就寫到這裏了,都是本身學習的經歷和理解,但願你們多多斧正,多多關注,感謝學習