鉤子函數的運行機理

在星球被問到鉤子函數的運行機理,感受很是有必要用一篇專門的文章來闡述一下,OK,我們快速的來過一下前端

1、什麼是鉤子

Vue 當中有鉤子函數,Git 的不少命令也有對應的 Hook,Webpack 的插件機制也是基於「鉤子」,不知道你第一次聽到鉤子這個詞是在什麼地方,若是都有所瞭解的話,那麼更須要來思考一下這之間的聯繫,我是這麼理解的:java

鉤子(hook)就是一些具備既定生命週期的框架工具,在生命週期的各個階段預留給用戶執行一些特定操做的口子,這實際上是一種面向切面編程webpack

這裏有兩個關鍵詞,既定的生命週期面向切面web

只有擁有既定的生命週期的框架工具才須要預留用戶自定義操做的口子,舉個簡單的栗子(對於不瞭解的同窗好像也未必簡單):gulp 的工做方式是定義一個串行的任務管道流,你能夠自由的拼接各類任務,這就叫作沒有既定的生命週期,這個時候鉤子毫無心義;可是 webpack 就不太同樣了,它已經定義好了分析、編譯、打包、輸出的整個工做流程,假若你想在編譯結束以後打包輸出以前作一些事情,而 webpack 又不給你任何介入的鉤子,那你的任何努力都會白費,這就是鉤子的意義所在,還記得下面這兩張圖出自哪篇文章麼?
spring

gulp 管道流
gulp 管道流

webpack 生命週期
webpack 生命週期

爲何還要提到面向切面,我第一次聽到這個詞仍是在寫 java 的時候,它是 spring 的核心思想之一(不得不說,前端從石器時代發展到今天的工業時代,大量借鑑了後臺的編程思想,所謂舉一反三,那個道理就是這麼講來着)。發揮想象力,所謂的鉤子,是否是在框架工具的某個階段,切一刀,插入一個或者多個特定的操做,想不清楚的都面壁思過去~~編程

2、鉤子的運行機理

前面說了,鉤子就是在框架工具的某個階段插一刀,執行一個或者多個特定的操做,那不就是調用一個或者多個用戶定義的函數麼?gulp

直接一點的,在框架工具生命週期的某個階段調用約定好的函數,例如 Vue,當組件渲染完畢,調用組件的 mounted 方法,當組件更新完畢,執行組件的 updated 方法框架

橫一點的,實現一套事件機制,在生命週期的某個階段,觸發特定的事件,執行註冊在該事件下的全部函數,說到事件,又有人頭皮發麻了,so,我又貼心的畫了一個圖:
函數

簡單的事件發佈訂閱機制
簡單的事件發佈訂閱機制

事件的發佈訂閱機制的核心在於 事件池,訂閱事件的一方將具體的操做 push 到事件池的某個 key 值下面,發佈事件的一方,找到事件池的某個 key 值下訂閱的全部函數依次執行(函數之間也有可能有依賴關係),秉承工具

天下難事必做於易

的信念,若是將上述的事件池經過一個內存中的 hashMap 來表示,你應該就能夠輕鬆的收入囊中了(類比Js的事件循環,其實只是用了獨立的線程來維護事件池)

其實不少框架工具的事件機制,還真的不過是一個 hashMap 來維護的那麼簡單,例如,Webpack 中採用的 Tapable

3、Tapable 介紹

以前在研究 webpack 的時候翻譯過 Tabpable 的文檔,迄今爲止,惟一的翻譯做品(尷尬~),由此去

4、後話

菲麥前端 是一個讓知識深刻原理的知識社羣,歡迎加微勾搭:facemagic2014

相關文章
相關標籤/搜索