前端異步解決方案-1(callback,事件監聽);

今天在學習koa2的時候發現本身對async的使用方法和原理都不是很熟悉,連帶着發現本身對前端異步的解決方案並瞭解並不如何深入,因此乾脆把前端現有的異步解決方案都複習了一遍。
今天先把將用callback事件監聽思想解決異步問題的代碼貼出來,明天再補充代碼的解析及其餘解決方案;前端

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’事件觸發了
事件監聽模式不用關心被綁定的函數何時執行,咱們只須要在特定的時候觸發對應的事件就能夠了。同時這個模式也程序至關的依賴事件,變成事件驅動,運行流程會變得很不清晰。函數


今天的文章就寫到這裏了,都是本身學習的經歷和理解,但願你們多多斧正,多多關注,感謝學習

相關文章
相關標籤/搜索