一杯咖啡☕️的時間,聊聊 js 異步解決方案
當前位置:點晴教程→知識管理交流
→『 技術文檔交流 』
回調函數(callback)回調函數 簡單理解就是一個函數被作為參數傳遞給另一個函數?;卣{是早期最常用的一種異步解決方案。 回調并不一定就是異步,并沒有直接關系。 舉個簡單的例子: function f1(cb) { setTimeout(() => { cb && cb(); }, 2000); } f1(() => { console.log("1"); }); 如上,我們使用 采用這種方式,我們把同步操作變成了異步操作, 回調優缺點優點:簡單、容易理解 缺點:代碼不優雅,可讀性差,不易維護,高度耦合,層層嵌套造成回調地獄 事件監聽(發布訂閱模式)發布訂閱模式 定義了對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都將會得到通知。 其實我們都用過發布訂閱模式,比如我們在 document.body.addEventListener('click', function () { console.log('點擊'); }) 但這只是對發布訂閱模式最簡單的使用,在很多場景下我們經常會使用一些自定義事件來滿足我們的需求。 發布訂閱模式有很多種實現方式,下面我們用 class Emitter { constructor() { // _listener數組,key為自定義事件名,value為執行回調數組-因為可能有多個 this._listener = [] } // 訂閱 監聽事件 on(type, fn) { // 判斷_listener數組中是否存在該事件命 // 存在將回調push到事件名對應的value數組中,不存在直接新增 this._listener[type] ? this._listener[type].push(fn) : (this._listener[type] = [fn]) } // 發布 觸發事件 trigger(type, ...rest) { // 判斷該觸發事件是否存在 if (!this._listener[type]) return // 遍歷執行該事件回調數組并傳遞參數 this._listener[type].forEach(callback => callback(...rest)) } } 如上所示,我們創建了一個 // 創建一個emitter實例 const emitter = new Emitter() emitter.on("done", function(arg1, arg2) { console.log(arg1, arg2) }) emitter.on("done", function(arg1, arg2) { console.log(arg2, arg1) }) function fn1() { console.log('我是主程序') setTimeout(() => { emitter.trigger("done", "異步參數一", "異步參數二") }, 1000) } fn1() 我們先創建一個 事件監聽優缺點優點:比較符合模塊化思想,我們自寫監聽器時可以做很多優化從而更好地監控程序運行。 缺點:整個程序變成了事件驅動,流程上或多或少都會有點影響,每次使用還得注冊事件監聽再進行觸發挺麻煩的,代碼也不太優雅。 PromiseES2015(ES6)標準化和引入了 簡單來說就是用同步的方式寫異步的代碼,可用來解決回調地獄問題。
我們用 function analogAsync(n) { return new Promise((resolve) => { setTimeout(() => resolve(n + 500), n); }); } function fn1(n) { console.log(`step1 with ${n}`); return analogAsync(n); } function fn2(n) { console.log(`step2 with ${n}`); return analogAsync(n); } function fn3(n) { console.log(`step3 with ${n}`); return analogAsync(n); } 用 function fn() { let time1 = 0; fn1(time1) .then((time2) => fn2(time2)) .then((time3) => fn3(time3)) .then((res) => { console.log(`result is ${res}`); }); } fn(); Promise 優缺點優點: 缺點: Generator
示例: function *generatorFn() { console.log("a"); yield '1'; console.log("b"); yield '2'; console.log("c"); return '3'; } let it = generatorFn(); it.next(); it.next(); it.next(); it.next(); 上面這個示例就是一個
Generator 優缺點優點:優雅的流程控制方式,可以讓函數可中斷執行 缺點: async/awaitES2017 標準引入了 async 在做什么
await 在等待什么
上述用 async function fn() { let time1 = 0; let time2 = await fn1(time1); let time3 = await fn2(time2); let res = await fn3(time3); console.log(`result is ${res}`); } fn(); 輸出結果和上面用 async/await 優缺點優點:內置執行器,更好的語義,更廣的適用性 缺點:濫用 該文章在 2023/7/29 9:42:29 編輯過 |
關鍵字查詢
相關文章
正在查詢... |