![](/img/trans.png)
[英]How do I sequence actions in RxJS/redux-observable vs redux-saga?
[英]Why use Redux-Observable over Redux-Saga?
我用過Redux-Saga 。 到目前為止,用它編寫的代碼很容易推理,除了 JS 生成器函數時不時地讓我頭疼。 根據我的理解, Redux-Observable可以實現類似的處理副作用但不使用生成器函數的工作。
然而,Redux-Observable 的文檔並沒有提供很多關於為什么它優於 Redux-Saga 的意見。 我想知道不使用生成器函數是否是使用 Redux-Observable 的唯一好處。 使用 Redux-Observable 而不是 Redux-Saga 可能有什么缺點、問題或妥協? 提前致謝。
免責聲明:我是redux-observable的作者之一,因此我很難100%公正。
我們目前沒有提供任何理由,redux-observable比redux-saga更好,因為......它不是。 😆
他們以極其相似的方式解決同樣的問題,但有一些基本的差異,只有在你足夠使用它們后才會變得非常明顯。
redux-observable幾乎將所有東西都推遲到慣用的RxJS。 因此,如果你有RxJS知識(或獲得它),學習和使用redux-observable是超級自然的。 這也意味着這種知識可以轉移到除redux之外的其他事物。 如果您決定切換到MobX,如果您決定切換到Angular2,如果您決定切換到未來的熱點X,那么RxJS可以幫助您的機會非常好。 這是因為RxJS是一個通用的異步庫,在很多方面就像編程語言本身 - 整個“反應式編程”范例。 RxJS自2012年開始存在,並作為Rx.NET的一個端口開始(幾乎所有主要語言都有“端口”,它非常有用 )。
redux-saga本身提供基於時間的運算符,因此雖然您獲得的有關生成器和處理副作用的知識在此流程管理器樣式中是可轉移的,但實際的運算符和用法並未在任何其他主要庫中使用。 所以這有點不幸,但當然不應該是一個交易破壞者。
它還使用“效果作為數據”( 此處描述 ),這可能很難首先解決,但這意味着你的redux-saga代碼實際上並沒有執行副作用。 相反,您使用的輔助函數創建的對象類似於表示執行副作用的意圖的任務,然后內部庫為您執行。 這使得測試非常簡單,無需嘲笑,對某些人來說非常有吸引力。 但是,我個人已經發現這意味着你的單元測試重新實現了你的saga的大部分邏輯 - 使這些測試不是很有用的IMO(這個觀點不是每個人共享的)
人們經常會問為什么我們不會使用redux-observable做類似的事情:對我而言,它與普通的慣用Rx根本不相容。 在Rx中,我們使用像.debounceTime()
那樣的運算符來封裝去抖動所需的邏輯,但是這意味着如果我們想要制作一個實際上不執行去抖動的版本,而是發出具有意圖的任務對象,那么''現在已經失去了Rx的力量,因為你不能僅僅依賴鏈接操作符,因為他們將在該任務對象上操作,而不是操作的真實結果。 這很難優雅地解釋。 它還需要對Rx有深入的了解才能理解方法的不兼容性。 如果你真的想要這樣的東西,請查看使用cycle.js的redux-cycles ,並且大多數都有這些目標。 我發現它需要太多的儀式來滿足我的口味,但我鼓勵你如果感興趣的話就給它一個旋轉。
正如ThorbenA所提到的,我不會回避承認redux-saga目前(10/13/16)是redux復雜副作用管理的明顯領導者。 它起步較早,擁有更強大的社區。 所以使用事實上的標准對於新的孩子來說有很大的吸引力。 我認為如果你在沒有先驗知識的情況下使用任何一種,你可能會有一些困惑。 我們都使用相當先進的概念,一旦你“獲得”,使復雜的副作用管理變得容易,但在此之前許多人絆倒了。
我能給出的最重要的建議是在你需要之前不要引入這些庫中的任何一個。 如果您只是進行簡單的ajax調用,則可能不需要它們。 redux-thunk簡單易學,為基礎提供了足夠的東西 - 但異步越復雜,對於redux-thunk來說就越難(甚至不可能)。 但是對於redux-observable / saga來說,它在很多方面都閃耀得越多,異步就越復雜。 在同一個項目中使用redux-thunk和其他一個(redux-observable / saga)也有很多優點! redux-thunk用於常見的簡單內容,然后僅使用redux-observable / saga進行復雜的操作。 這是保持工作效率的好方法,所以你不會為了使用redux-thunk這些微不足道的事情而與redux-observable / saga作斗爭。
我認為有些事情你需要考慮。
讓我們說我們想從API中獲取用戶
// Redux-Saga
import axios from 'axios'
function* watchSaga(){
yield takeEvery('fetch_user', fetchUser) // waiting for action (fetch_user)
}
function* fetchUser(action){
try {
yield put({type:'fetch_user_ing'})
const response = yield call(axios.get,'/api/users/1')
yield put({type:'fetch_user_done',user:response.data})
} catch (error) {
yield put({type:'fetch_user_error',error})
}
}
// Redux-Observable
import axios from 'axios'
const fetchUserEpic = action$ =>
action$
.ofType('fetch_user')
.flatMap(()=>
Observable.from(axios.get('/api/users/1')) // or use Observable.ajax
.map(response=>({type:'fetch_user_done', user:response.data}))
.catch(error => Observable.of({type:'fetch_user_error',error}))
.startWith({type:'fetch_user_ing'})
)
另外,我寫這篇文章是為了深入比較Redux-saga和Redux-Observable之間的差異。 在這里查看此鏈接或演示文稿 。
我使用Redux-Observable而不是Redux-Saga,因為我更喜歡使用可觀察量而不是生成器。 我將它與RXJS一起使用,RXJS是一個用於處理數據流的強大庫。 把它想象成為異步的lodash。 在任何缺點方面,在選擇其中一個方面存在問題和妥協,請看看Jay Phelps的答案 :
redux-saga作為一個項目存在的時間比redux-observable更長,所以這肯定是一個主要的賣點。 您將找到更多文檔,示例,並且可能有更好的社區來獲得支持。
計數器是你在redux-saga中學到的運算符和API幾乎不像學習RxJS那樣可轉移,RxJS遍布各地。 redux-observable是超級超級簡單的內部,它真的只是給你一個自然的方式來使用RxJS。 所以如果你知道RxJS(或者想要),那就非常自然了。
我對大多數人的建議是,如果你不得不問你應該使用哪一個,你可能應該選擇redux-saga。
我重視Rx具有的語言和運行時的可轉移性。 即使您的應用不會改變語言,您的職業生涯也可能如此。 在您的學習中獲得最佳的杠桿作用,無論您為自己規模如此。 它特別適合.Net LINQ。
Redux-Observable是一個了不起的圖書館,我們在生產中使用它已經有1.5年沒有任何問題到目前為止,它完全可以測試,可以很容易地與任何框架集成。 我們擁有極度超載的並行套接字通道,唯一可以讓我們免於凍結的是Redux-Observable
我想在這里提到3點。
1.復雜性和學習曲線
Redux-saga在這里輕松擊敗redux-observable。 如果您只需要一個簡單的請求來完成授權而且您不想因為某些原因而使用redux-thunk,那么您應該考慮使用redux-saga,它更容易理解。
如果您沒有Observable的先驗知識,那將是您的痛苦,您的團隊將為您服務:)
2. Observable和RxJS能為我提供什么?
說到異步邏輯Observable是你的瑞士刀,Observable可以為你做幾乎所有事情。 你永遠不應該將它們與承諾或發電機進行比較,它更強大,就像比較擎天柱和雪佛蘭一樣。
那么RxJS呢? 它就像lodash.js,但對於異步邏輯,一旦你進入你就永遠不會切換到不同的東西。
3.無功擴展
只需查看此鏈接即可
針對所有現代編程語言實現了反應式擴展,它只是函數式編程的關鍵。
所以花時間明智地學習RxJS並使用redux-observable :)
如果你寫的打字稿您的應用程序,我建議你檢查無類型。 它受到 Redux-Observable 的啟發,也依賴於 RxJS,但有用於構建應用程序的整個生態系統。
redux-observable/redux-saga 的最大缺點是缺乏指導方針。 沒有關於如何延遲負載減速器、傳奇或史詩的官方指南。 在擴展更大的應用程序時,代碼拆分至關重要。 延遲加載的自定義解決方案通常不適用於 HMR,從而導致開發人員體驗不佳。
由於這里有一大堆redux-observable談話,我以為我會給出論證的傳奇方面。 我不使用redux-observable或RxJS,所以我不能進行並排比較,但我使用了傳奇效果很好。
為了它的價值,我在網絡應用程序中使用sagas。
佐賀贏得了勝利。 我不喜歡thunk如何將邏輯放入我的動作創作者中。 它也連續做了幾個請求麻煩。 我簡要地看了一下redux-observable的這份工作,但是他確定了Sagas。
了解生成器是什么以及它們為什么重要是理解傳奇的關鍵。 但我強調的是,你並不需要內部和外部的認識發電機。 您只需要知道您使用yield語句傳遞控制權,並且在異步代碼解析后,saga將傳回控制權。 在那之后,它不是很難理解傳奇中發生了什么。
核心傳奇方法是(根據我的經驗):
call
- 調用任何代碼並獲取返回值。 支持承諾。 異步處理和傳奇之間的巨大協同作用。 select
- 調用選擇器。 這一點非常棒。 選擇器是redux的核心,它們是100%支持的! put
-又名dispatch
一個動作。 事實上,您可以根據需要調度! 還有其他功能,但是如果你能掌握這三個功能,你將會處於一個非常好的位置。
我選擇傳奇的原因是易用性。 redux-observable看起來像是一個挑戰。 我對傳奇100%滿意。 比我想象的更開心。
根據我的經驗,Sagas(方式)比thunk更好,相對容易理解。 Rx不是每個人的一杯茶。 如果你不是來自那個生態系統和/或不打算將來使用Rx,我會強烈考慮sagas而不是redux-observable。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.