[TOC]
# 冪等性
* 所謂冪等性通俗的將就是一次請求和多次請求同一個資源產生相同的副作用。
數學語言表達就是`f(x)=f(f(x))`。
* 維基百科的冪等性定義如下:
~~~
冪等(idempotent、idempotence)是一個數學與計算機學概念,常見于抽象代數中。?在編程中一個冪等操作的特點是其任意多次執行所產生的影響均與一次執行的影響相同。冪等函數,或冪等方法,是指可以使用相同參數重復執行,并能獲得相同結果的函數。這些函數不會影響系統狀態,也不用擔心重復執行會對系統造成改變。例如,“setTrue()”函數就是一個冪等函數,無論多次執行,其結果都是一樣的,更復雜的操作冪等保證是利用唯一交易號(流水號)實現.
~~~
在編程中,一個冪等操作的特點是其任意多次執行所產生的影響均與一次執行的影響相同。冪等函數或冪等方法是指可以使用相同參數重復執行,并能獲得相同結果的函數 / 方法。這些函數 / 方法不會影響系統狀態,因此不用擔心重復執行會對系統造成改變。例如:
1. 前端重復提交選中的數據,后臺也只會產生對應這個數據的一個反應結果。
2. 用戶發起一筆付款請求,就應該只扣用戶一次錢,即使遇到網絡重發或系統 bug 重發請求,也應該之扣一次錢。
3. 發送驗證短息也應該只發一次,同樣的驗證短信不應該發送多次。
4. 創建業務訂單,一個業務請求只能創建一個業務訂單,創建多個就會出大問題。
這些等等很多的業務邏輯都需要冪等的特性來支持。
簡單來理解就是,冪等就是一個操作,這個操作不管執行多少次,產生的效果和返回的結果都是一樣的。比如說有一個 getOne () 函數,無論執行這個函數多少次,它返回的都是 1,這時就可以說它是一個冪等函數。
# 為什么需要冪等性
* 在系統高并發的環境下,很有可能因為網絡,阻塞等等問題導致客戶端或者調用方并不能及時的收到服務端的反饋甚至是調用超時的問題。總之,就是請求方調用了你的服務,但是沒有收到任何的信息,完全懵逼的狀態。比如訂單的問題,可能會遇到如下的幾個問題:
1. 創建訂單時,第一次調用服務超時,再次調用是否產生兩筆訂單?
2. 訂單創建成功去減庫存時,第一次減庫存超時,是否會多扣一次?
3. 訂單支付時,服務端扣錢成功,但是接口反饋超時,此時再次調用支付,是否會多扣一筆呢?
* 作為消費者,前兩種能接受,第三種情況就 MMP 了,哈哈哈!!!這種情況一般有如下兩種解決方式
1. 服務方提供一個查詢操作是否成功的 api,第一次超時之后,調用方調用查詢接口,如果查到了就走成功的流程,失敗了就走失敗的流程。
2. 另一種就是服務方需要使用冪等的方式保證一次和多次的請求結果一致。
# 參考
[接口冪等性如何實現?](http://blog.itpub.net/69969697/viewspace-2683852/)
[如何做到接口的冪等性](https://cloud.tencent.com/developer/article/1526642)
[冪等性如何實現?深入了解一波!!!](https://mp.weixin.qq.com/s?__biz=MzI0ODYzMzIwOA==&mid=2247483974&idx=1&sn=1b71a961636a08aba0b973240df5697b&chksm=e99c8051deeb0947c99f23cdcc2bffacbcb6c4334900bde8c4b627e327213daf11acfffa4703&scene=126&sessionid=1585200996&key=bd873186532b9f4effc489fedbc274400872c0b6a0f4a1eb1e1700cca311c7588c1f2661a73f5321d7143316f249b15e849c1f6b0fe55a85f9268878a171afbc975e667a5e71c592b8528b50e7f1ce72&ascene=1&uin=MTA3MjI0MTk2&devicetype=Windows+10&version=62080079&lang=zh_CN&exportkey=ATKxWBRhz%2BdeVp89aixV7gg%3D&pass_ticket=26t9iuszGw1evGgO2rFoWR%2BnItByEBiAoFQcBTZ4NG4%3D)
- 修仙之路
- 基礎原理篇
- JS和Node.js事件環機制剖析
- 一圖理解原型鏈
- 手寫篇
- 基礎手寫
- 手寫實現 Promise A+ 類庫
- 手寫 CommonJS
- 手寫 Express 框架
- 手寫 React Router 4.0
- 手寫虛擬 DOM 和 DOM-Diff
- 手寫 Webpack 實現
- 手寫一個 MVVM 類庫
- 手寫一個 Vue-cli 腳手架
- 手寫 JWT 類庫
- 手寫 Mobx 類庫
- 手寫前端性能和錯誤監控框架
- 手寫 Vue 路由
- 手寫 Vuex 實現
- 手寫 redux 狀態容器
- 手寫 throttle 和 debounce
- Node 高級
- Mongodb
- 安全測試篇
- CSRF原理實現
- XSS原理實現
- 九種跨域方法全解析
- 編寫單元測試
- 爬蟲篇
- 使用puppeteer破解滑動驗證碼
- 工程篇
- 使用AST語法樹手工轉譯ES6代碼
- 編寫自己的webpack插件
- 實戰篇
- webpack4.0 實戰
- Canvas+Websocket 實現彈幕
- canvas 動效
- SVG 動效
- CSS3 實現 Apple Watch 中的呼吸燈效果
- CSS3 實現動態氣泡屏保效果
- 算法篇
- 基礎知識
- 服務器端
- 分布式架構中的冪等性
- TCP/UDP
- Docker
- V8
- 動畫篇
- 貝塞爾曲線
- requestAnimationFrame
- 框架篇
- 隨記