摘要:跨域,對後端工程師來說,可謂既熟悉又陌生。 本文分享自華為雲社區《後端老司機的跨域之旅》,作者: 勇哥java實戰分享。 跨域,對後端工程師來說,可謂既熟悉又陌生。 這兩個月我以架構師的角色參與一款教育產品的孵化,有了一段難忘的跨域之旅。 寫這篇文章,我想分享我在跨域這個知識點的經歷和思考,希 ...
1. 裝飾器模式
1.1. 擴展對象的行為,而不必修改對象的類
1.2. 裝飾的對象可以執行其原始實現沒有提供的功能
1.3. 優勢
1.3.1. 支持單一職責原則
1.3.1.1. 每個類只應該承擔一種職責
1.4. 經典實現
1.4.1. 一個IComponent介面
1.4.2. 一個具體實現,即ConcreteComponent
1.4.3. 使用額外行為來增強IComponent的Decorator
1.4.3.1. 例如:添加單例行為
1.4.4. 特點
1.4.4.1. 一個介面
1.4.4.1.1. 介面聲明瞭多個方法,就無法使用一個函數類型來替代介面
1.4.4.2. 兩個類
1.4.4.3. 每個類一個方法
1.4.4.3.1. 具體操作
1.4.4.3.2. 裝飾器
1.5. 函數裝飾器
1.5.1. 介面改為一個函數類型
1.5.1.1. 示例:該類型的函數不接受實參,返回一個Widget:() => Widget
1.5.2. 一個具體實現的類替換為簡單函數
1.5.3. 一個新函數singletonDecorator()
1.5.3.1. 接受一個WidgetFactory類型的函數
1.5.3.2. 返回另外一個WidgetFactory類型的函數
1.5.3.3. 採用lambda實現
1.5.4. 特點
1.5.4.1. 一個函數類型
1.5.4.1.1. 工廠函數類型
1.5.4.2. 兩個函數
1.5.4.2.1. 工廠函數
1.5.4.2.2. 裝飾器函數
1.6. 閉包
1.6.1. lambda捕獲
1.6.1.1. lambda內捕獲的一個外部變數
1.6.2. 編程語言通過閉包來實現lambda捕獲
1.6.3. 閉包記錄了創建該函數時的環境
1.6.3.1. 可以在不同調用之間維護狀態
1.6.4. lambda引用了函數的局部變數
1.6.4.1. 其生存期將大於創建它的函數
1.6.4.2. 函數的局部變數在調用函數時創建,在函數返回時銷毀
1.6.5. 保留了其外層函數的一些狀態信息的lambda
1.6.6. 只有存在高階函數,閉包才有意義
1.6.6.1. 不能從一個函數中返回另一個函數,就不存在要捕獲的環境
1.6.6.2. 所有函數都在全局作用域內,所以全局作用域就是它們的環境
1.6.6.2.1. 函數只能引用全局變數
1.6.7. 對象代表一組方法的某個狀態
1.6.8. 閉包則代表捕獲到某個狀態的函數
2. 計數器
2.1. 全局計數器
2.1.1. 一個引用全局變數的簡單函數
2.1.2. 缺點
2.1.2.1. 計數器的值沒有被恰當封裝
2.1.2.2. 不能使用計數器的兩個獨立的實例
2.2. 面向對象的計數器
2.2.1. 多個獨立的計數器
2.3. 函數式計數器
2.3.1. 代碼比面向對象版本的更加簡潔
2.4. 可恢復的計數器
2.4.1. 可恢復的函數
2.4.1.1. 跟蹤自己狀態的函數,在被調用時,不會從頭運行,而是從上一次返回時所在的狀態恢復執行
2.4.2. 不使用關鍵字return來退出函數
2.4.3. 使用關鍵字yield
2.4.3.1. 必須把函數聲明為一個生成器
2.4.3.2. 其返回類型必須是可迭代的迭代器
2.4.3.3. 在函數名稱的前面加上星號來聲明生成器
2.4.4. TypeScript語法
2.4.5. 生成器通過特殊語法來創建可恢復的函數
2.4.6. 生成器不是返回控制權,而是交出控制權
3. 非同步
3.1. 按順序運行代碼可能導致不可接受的延遲
3.2. 回調
3.2.1. 作為實參提供給非同步函數的一個函數
3.2.2. 也可以從非同步函數那裡收到實參
3.3. 非同步執行模型
3.3.1. 線程
3.3.2. 事件迴圈
3.3.2.1. 使用一個隊列
3.3.2.2. 非同步函數將被加入隊列
3.3.2.3. 它們自己也可以將其他函數排隊
3.3.2.4. 只要隊列不為空,隊列中的第一個函數就將被取出來執行
3.3.2.5. 優點
3.3.2.5.1. I/O操作等待數據時讓它們排隊的效果很好
3.3.2.5.2. 不需要同步,因為所有代碼在一個線程上運行
3.3.2.6. 缺點
3.3.2.6.1. 對於運行時間長,但是不能被拆分為多個操作的任務,效果不好
3.3.2.6.2. CPU密集的操作會造成阻塞
3.3.2.6.2.1. CPU密集的操作(如複雜計算)不能被排隊
3.3.2.6.2.2. 需要CPU周期
3.3.2.6.2.3. 沒有等待數據
3.4. 簡化非同步代碼
3.4.1. promise
3.4.1.1. 將來某個時刻可用的值的一個代理
3.4.1.2. 在生成該值的代碼運行之前,其他代碼可以使用該promise設置在該值可用後如何處理該值,在發生錯誤時如何處理,甚至取消將來的執行
3.4.1.3. 讓代碼的可讀性相比使用回調時更好
3.4.1.4. 狀態
3.4.1.4.1. 等待(pending)
3.4.1.4.1.1. 已被創建,但還沒有完成
3.4.1.4.2. 完成(settled)
3.4.1.4.2.1. 已經調用了,並提供了一個值,此時將調用continuation
3.4.1.4.3. 拒絕(rejected)
3.4.1.4.3.1. 調用reject()或者拋出錯誤
3.4.1.4.3.1.1. 當前的promise會被拒絕
3.4.1.4.3.1.2. 通過then()鏈接到該promise的其他所有promise都會被拒絕