讀編程與類型系統筆記06_函數類型的高級應用

来源:https://www.cnblogs.com/lying7/archive/2023/01/13/17048493.html
-Advertisement-
Play Games

摘要:跨域,對後端工程師來說,可謂既熟悉又陌生。 本文分享自華為雲社區《後端老司機的跨域之旅》,作者: 勇哥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都會被拒絕

3.4.1.5. 組合promise

3.4.1.5.1. Promise.all()
3.4.1.5.1.1. 一組promise作為實參
3.4.1.5.1.2. 返回當提供的所有promise都完成後完成的一個promise
3.4.1.5.2. Promise.race()
3.4.1.5.2.1. 一組promise作為實參
3.4.1.5.2.2. 返回當提供的任何一個promise完成時完成的一個promise

3.4.2. continuation

3.4.2.1. 在promise的結果可用後調用的函數

3.4.2.2. 並非必須返回一個promise

3.4.2.2.1. 不是總會鏈接非同步函數
3.4.2.2.2. 可以同步執行
3.4.2.2.3. 自動轉換為Promise

3.4.2.3. 每個continuation放到一個單獨的函數中,並通過then()把它們鏈接起來

3.4.3. 函數promise提供給我們某個類型T的值,以及指定從T到其他某個類型U的函數((value: T)=> U)的能力,當承諾被履行,我們得到了值以後,將調用這個函數(它就是continuation)

3.4.4. JavaScript(及TypeScript)採用Promise類型實現

3.4.5. C#採用Task實現

3.4.6. JAVA採用CompletableFuture實現

3.4.7. async/await

3.4.7.1. 代碼的可讀性更好

3.4.7.1.1. 非同步代碼讀起來類似於同步代碼

3.4.7.2. 把所有代碼寫到一個函數中,每當調用另外一個返回promise的函數,就等待(await)其結果,然後在得到結果後繼續執行

3.4.7.3. 異常將從await調用拋出,可在try/catch語句中捕獲

3.4.7.4. 不使用then()提供continuation

3.4.7.5. 語法糖


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 摘要:輸入網址並點回車,後臺到底發生了什麼。透析 HTTP 協議與 TCP 連接之間的千絲萬縷的關係。掌握為何是三次握手四次揮手?time_wait 存在的意義是什麼?全面圖解重點問題,再也不用擔心面試問這個問題。 本文分享自華為雲社區《輸入網址,小手一點,後面到底發生了什麼?》,作者:龍哥手記。 ...
  • 1.按鈕點擊後添加loading,介面返回成功後再移除loading(經過多次嘗試發現,此方法不能完全確保只調用一次介面,第二次添加時仍會多次調用介面),方法如下: html代碼: <el-button @click="onSave" :loading="onLoading">保存</el-butt ...
  • JavaScript 中,對於普通對象,不能直接使用 length 來獲取對象的長度,因為 JavaScript 對象並不是一種有序的集合,沒有長度的概念。 對於數組或者類數組對象,可以使用 .length 來獲取它們的長度,因為它們是有序集合。 對於字元串也可以使用.length來獲取長度,因為字... ...
  • 我們是袋鼠雲數棧 UED 團隊,致力於打造優秀的一站式數據中台產品。我們始終保持工匠精神,探索前端道路,為社區積累並傳播經驗價值。 前言 訪問控制(Access control)是指對訪問者向受保護資源進行訪問操作的控制管理。該控制管理保證被授權者可訪問受保護資源,未被授權者不能訪問受保護資源。 現 ...
  • 在 CSS 中,倒影是一種比較常見的效果。今天,我們就將嘗試,使用 CSS 完成各類不同的倒影效果,話不多說,直接進入主題。 實現倒影的兩種方式 首先,快速過一下在 CSS 中,實現倒影的 2 種方式。 使用 -webkit-box-reflect 正常而言,-webkit-box-reflect ...
  • 基於AWS雲SaaS多租戶架構設計租戶與用戶概念單租戶與多租戶多租戶的好處 採用多租戶架構方法將為你的SaaS應用程式帶來廣泛的有價值的好處。 讓我們來看看下麵的貢獻。 a) 利用多租戶架構策略,減少伺服器基礎設施成本。 與其為每個客戶創建一個SaaS環境,不如為所有客戶提供一個應用環境。這使你的A ...
  • 隨著互聯網的發展,用戶在使用網路時對網站的瀏覽速度和效果愈加重視,但由於網民數量激增,網路訪問路徑過長,從 而使用戶的訪問質量受到嚴重影響。特別是當用戶與網站之間的鏈路被突發的大流量數據擁塞時,對於異地互聯網用戶急速增加的地區來說,訪問質量不良更是一個 急待解決的問題。如何才能讓各地的用戶都能夠進行 ...
  • 作為一個後端研發人員,開發服務介面是我正常不過的工作了,這些介面不管是面向前端HTTP或者是供其他服務RPC遠程調用的,都繞不開一個共同的話題就是“高可用”,介面開發往往看似簡單,但保證高可用這塊實現起來卻不並沒有想想的那麼容易,接下來我們就看一下,一個高可用的介面是該考慮哪些內容,同時文中有不足的... ...
一周排行
    -Advertisement-
    Play Games
  • 一:背景 1. 講故事 年前遇到了好幾例托管堆被損壞的案例,有些運氣好一些,從被破壞的托管堆記憶體現場能觀測出大概是什麼問題,但更多的情況下是無法做出準確判斷的,原因就在於生成的dump是第二現場,借用之前文章的一張圖,大家可以理解一下。 為了幫助更多受此問題困擾的朋友,這篇來整理一下如何 快狠準 的 ...
  • 前言 .NET6 開始,.NET Croe API 項目取消了 Startup.cs 文件,在 Program.cs 文件的 Main 函數中完成服務的註冊和中間件管道的管理。但當我們項目引入更多包的時候,Program.cs 文件也會看起來很臃腫。 而且,我們不只會有一個後端項目,為了方便快速創建 ...
  • 目錄 背景 get 與 post 的區別 所有介面都用 post 請求? 背景 最近在逛知乎的時候發現一個有趣的問題:公司規定所有介面都用 post 請求,這是為什麼? 看到這個問題的時候其實我也挺有感觸的,因為我也曾經這樣問過我自己。在上上一家公司的時候接到一個項目是從零開始搭建一個微服務,當時就 ...
  • *以下內容為本人的學習筆記,如需要轉載,請聲明原文鏈接 微信公眾號「englyf」https://mp.weixin.qq.com/s/2GFLTstDC7w6u3fTJxflNA 本文大概 1685 個字,閱讀需花 6 分鐘內容不多, 但也花了一些精力如要交流, 歡迎關註我然後評論區留言 謝謝你的 ...
  • 在新版本的pandas中,上述代碼會引起警告,建議改成SQLAlchemy connectable(engine/connection),後續代碼將引入這種升級的連接方式。 ...
  • 幾乎所有的高級編程語言都有自己的垃圾回收機制,開發者不需要關註記憶體的申請與釋放,Python 也不例外。Python 官方團隊的文章 https://devguide.python.org/internals/garbage-collector 詳細介紹了 Python 中的垃圾回收演算法,本文是這篇 ...
  • 如果您想查找高於或低於平均值的數字,可以不必計算該平均值,就能查看更高或更低的值。通過Java應用程式,可以自動突出顯示這些數字。除了快速突出顯示高於或低於平均值的值外,您還可以查看高於或低於的值的個數。現在讓我們看看如何在 Java應用程式中實現此操作。 引入jar包 導入方法1: 手動引入。將  ...
  • 第一種方式:使用{} firstDict = {"name": "wang yuan wai ", "age" : 25} 說明:{}為創建一個空的字典對象 第二種方式:使用fromkeys()方法 second_dict = dict.fromkeys(("name", "age")) #valu ...
  • 在golang中可以使用a := b這種方式將b賦值給a,只有當b能進行深拷貝時a與b才不會互相影響,否則就需要進行更為複雜的深拷貝。 下麵就是Go賦值操作的一個說明: Go語言中所有賦值操作都是值傳遞,如果結構中不含指針,則直接賦值就是深度拷貝;如果結構中含有指針(包括自定義指針,以及切片,map ...
  • 本文結合京東監控埋點場景,對解決樣板代碼的技術選型方案進行分析,給出最終解決方案後,結合理論和實踐進一步展開。通過關註文中的技術分析過程和技術場景,讀者可收穫一種樣板代碼思想過程和解決思路,並對Java編譯器底層有初步瞭解。 ...