Redux-Saga yerine neden Redux-Observable kullanılıyor?


133

Ben kullandım Redux-Saga . Onunla yazılmış kod şimdiye kadar mantıklı, ancak JS oluşturucu işlevi zaman zaman kafamı karıştırıyor. Anladığım kadarıyla Redux-Observable , yan etkileri ele alan benzer bir işi ancak jeneratör işlevini kullanmadan başarabilir.

Bununla birlikte, Redux-Observable'dan gelen dokümanlar, Redux-Saga'ya karşı neden üstün olduğuna dair pek çok fikir sağlamıyor. Redux-Observable'ı kullanmanın tek faydasının jeneratör işlevini kullanmama olup olmadığını bilmek isterim. Ve Redux-Saga yerine Redux-Observable'ı kullanmanın olumsuz yanları, elde ettikleri veya tavizleri ne olabilir? Şimdiden teşekkürler.


Redux-Saga'yı, bütün gün gözlemlenebilir yaşamayan / yemek yemeyen / nefes almayan insanlar için Redux-Observable'dan daha üstün bulduğum eğlenceli ama detaylı bir blog yapmıştım. Eminim yığınınızın tamamı gözlenebilir ise harikadır. shift.infinite.red/…
Gant Laborde

Yanıtlar:


236

Sorumluluk reddi: Redux-observable'ın yazarlarından biriyim, bu yüzden% 100 tarafsız olmak benim için zor.

Şu anda redux-observable'ın redux-saga'dan daha iyi olduğuna dair herhangi bir neden sunmuyoruz çünkü ... öyle değil. 😆

tl; dr her ikisinin de artıları ve eksileri vardır. Birçoğu birini diğerinden daha sezgisel bulacaktır, ancak RxJS'yi (yeniden gözlemlenebilir) veya üreteçleri / "veri olarak etkileri" (redux-saga) bilmiyorsanız, her ikisini de farklı şekillerde öğrenmek karmaşıktır.

Aynı sorunu son derece benzer yollarla çözerler, ancak ancak yeterince kullandığınızda gerçekten belirgin hale gelen bazı temel farklılıklara sahiptirler.

redux-observable neredeyse her şeyi deyimsel RxJS'ye erteliyor. Dolayısıyla, RxJS bilgisine sahipseniz (veya kazanıyorsanız), redux-observable'ı öğrenmek ve kullanmak çok doğaldır. Bu aynı zamanda, bu bilginin redux dışındaki şeylere aktarılabilir olduğu anlamına gelir. MobX'e geçmeye karar verirseniz, Angular2'ye geçmeye karar verirseniz, gelecekteki bir sıcaklığa X geçmeye karar verirseniz, RxJS'nin size yardımcı olma ihtimali son derece yüksektir. Bunun nedeni, RxJS'nin genel bir eşzamansız kitaplık olması ve birçok yönden kendi başına bir programlama dili gibi olmasıdır — tüm "Reaktif Programlama" paradigması. RxJS, 2012'den beri var olmuştur ve bir Rx.NET portu olarak başlamıştır (hemen hemen her ana dilde "portlar" vardır, bu kadar yararlıdır ).

redux-saga, zamana dayalı operatörlerini kendisi sağlar, bu nedenle bu süreç yöneticisi stilinde jeneratörler ve yan etkileri ele alma hakkında edindiğiniz bilgiler aktarılabilirken, gerçek operatörler ve kullanım başka herhangi bir büyük kütüphanede kullanılmaz. Yani bu biraz talihsiz bir durum, ancak kesinlikle tek başına bir anlaşma bozucu olmamalı.

Aynı zamanda "veri olarak efektler" ( burada açıklanmıştır ) kullanır, bu da ilk başta başınızı sarmak zor olabilir, ancak bu, redux-saga kodunuzun aslında yan etkileri kendi başına gerçekleştirmediği anlamına gelir. Bunun yerine, kullandığınız yardımcı işlevler, yan etkiyi yapma amacını temsil eden görevlere benzeyen nesneler oluşturur ve ardından dahili kitaplık bunu sizin için gerçekleştirir. Bu, alay etmeye gerek kalmadan testi son derece kolaylaştırır ve bazı insanlar için çok caziptir. Bununla birlikte, şahsen bunun, birim testlerinizin saga mantığınızın çoğunu yeniden uyguladığı anlamına geldiğini buldum - bu testleri çok yararlı IMO yapmaz (bu görüş herkes tarafından paylaşılmaz)

İnsanlar sık ​​sık redux-observable ile neden böyle bir şey yapmadığımızı soruyorlar: bana göre bu, normal deyimsel Rx ile temelde uyumsuz. .debounceTime()Rx'te, geri çevirmek için gerekli mantığı kapsayan bu tür operatörler kullanıyoruz , ancak bunun anlamı, gerçekten hata giderme işlemini gerçekleştirmeyen ve bunun yerine görev nesnelerini niyetle yayınlayan bir versiyonunu yapmak istersek, artık Rx'in gücü, çünkü artık operatörleri zincirleyemezsiniz çünkü operasyonun gerçek sonucu değil, o görev nesnesi üzerinde çalışıyor olacaklardır. Bunu zarif bir şekilde açıklamak gerçekten zor. Yaklaşımların uyumsuzluğunu anlamak için yine Rx'in iyice anlaşılmasını gerektirir. Eğer varsa gerçekten böyle bir şey istiyorum, kontrol redux-döngüleriBu, cycle.js'yi kullanan ve çoğunlukla bu hedeflere sahip. Zevklerime göre çok fazla tören gerektirdiğini düşünüyorum, ancak ilginizi çekiyorsa bir deneme yapmanızı tavsiye ederim.

ThorbenA'nın da belirttiği gibi, redux-saga'nın şu anda (10/13/16) redux için karmaşık yan etki yönetiminde açık lider olduğunu kabul etmekten çekinmiyorum. Daha önce başladı ve daha sağlam bir topluluğa sahip. Bu yüzden, bloktaki yeni çocuk yerine fiili standardı kullanmak çok cazip. Ya önceden bilgi sahibi olmadan kullanırsanız, biraz kafa karışıklığı yaşadığınızı söyleyebilirim. İkimiz de oldukça gelişmiş konseptler kullanıyoruz ve bir kez "elde ettiğinizde" karmaşık yan etki yönetimini çok daha kolay hale getiriyor, ancak o zamana kadar birçok kişi tökezliyor.

Verebileceğim en önemli tavsiye, bu kütüphanelerden herhangi birine ihtiyaç duymadan getirmemenizdir. Yalnızca basit ajax aramaları yapıyorsanız, muhtemelen onlara ihtiyacınız yoktur. redux-thunk öğrenmesi aptalca basittir ve temel bilgiler için yeterince sağlar - ancak eşzamansız ne kadar karmaşıksa, redux-thunk için o kadar zor (hatta imkansız) hale gelir. Ancak birçok yönden redux-observable / saga için, async ne kadar karmaşıksa o kadar çok parlar. Aynı projede diğerlerinden biriyle (redux-observable / saga) redux-thunk kullanmanın da büyük bir değeri var! genel basit şeyleriniz için redux-thunk ve daha sonra karmaşık şeyler için yalnızca redux-observable / saga kullanın. Bu üretken kalmanın harika bir yolu, bu yüzden redux-thunk ile önemsiz olan şeyler için redux-observable / saga ile savaşmıyorsunuz.


3
Sadece konuşmanızı gördüm (uuhf sesi!) Ve hemen ⌘ + T + "redux-saga vs redux-observable" e basın. Redux-saga'yı epey bir süredir kullanıyorum (özellikle React Native'de), ancak konuşmanızı ve bu gönderiyi izledikten sonra redux-obs'ların (benim için) bazı kullanım durumlarını görebiliyorum. aslında daha uygun olur. debounceTime()Çok genel bir mantık üzerindeki kontrolünü "kaybetmiş" olmanla ilgili örneğiniz benim için onu vurdu. Açıkladığınız için teşekkürler.
Hulvej

3
Sadece konuşmayı da gördüm ve biraz daha googling yaptım. İyi şeyler @jayphelps, paylaştığınız için teşekkürler. Redux-thunk ile birlikte redux-observable / saga ile ilgili yorumunuzu özellikle beğeniyorum. Bu çok mantıklı, neden gereksiz olduğunda basit AJAX isteklerini aşırı karmaşık hale getiriyor? Bununla birlikte, tekdüzelik ve insanları tutarlı tutmak için söylenecek bir şeyler var. Tekrar teşekkürler!
Spets

Redux-saga / redux-observable sürümüne yükseltme yapmadan önce, çok basit olan ve bazı kullanım durumlarınızı zaten çözebilecek olan redux-dispatch-listener'ı deneyebilirsiniz: github.com/slorber/redux-dispatch-subscribe
Sebastien Lorber,

Bu çok faydalı bir cevaptı. Teşekkür ederim! RxJS bilgisini diğer alanlara / çerçevelere aktarabilme noktasını seviyorum.
Anselan

@jayphelps "Karmaşık eşzamansız" örneği ne olabilir? Şu anda bir proje için thunk'tan destan / gözlemlenebilirlere geçip geçmemeyi değerlendirmeye çalışıyorum. Teşekkürler :)
Sam Bokai

64

Bence dikkate almanız gereken şeyler var.

  1. karmaşa
  2. Kodlama Stili
  3. Öğrenme eğrisi
  4. Testedilebilirlik

Kullanıcıyı API'den getirmek istediğimizi varsayalım

// 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'})
        )

Ayrıca Redux-saga ve Redux-Observable arasındaki farkları derinlemesine karşılaştırmak için bu makaleyi yazdım. Bu bağlantıya veya sunuma göz atın .


3
bağlantıdan gelen bu yan yana karşılaştırma harika, teşekkürler
rofrol

1
Karşılaştırmayı seviyorum, ANCAK bununla ilgili gündeme getirmek istediğim bir sorun var. Bunları api çağrılarını kullanarak karşılaştırdığınızda - redux-observable için getirme kullanıyorsunuzdur. güzel. ANCAK, "iptal edilebilir" farklılıklar gösterdiğinde .. getirme KULLANMAZ - bunun yerine dahili Observable.ajax kullanırsın ... neden? "Getir" veya "axios" kullanarak kalmasını tercih ederim. aksi takdirde, orada harika iş çıkardınız.
james emanon

5
@jamesemanon Getirme API'sinin henüz iptal etme seçeneği olmadığı için getirmeyi kullanmadığını varsayıyorum. (bu konuyla ilgili daha fazla bilgi için: github.com/whatwg/fetch/issues/27 )
Daniel Andrei

Vay canına, tüm örneklerle derinlemesine karşılaştırma yapmak en iyisidir. Teşekkür ederim!
Radek Matěj

22

Redux-Saga yerine Redux-Observable kullanıyorum çünkü jeneratörler yerine gözlemlenebilirlerle çalışmayı tercih ediyorum. Veri akışlarıyla çalışmak için güçlü bir kitaplık olan RXJS ile kullanıyorum. Asenkron için lodash gibi düşün. Herhangi bir dezavantajı, birini diğerinin üzerine seçmenin getirdiği tavizler ve tavizler açısından, Jay Phelps'in şu cevabına bir göz atın :

redux-saga, bir proje olarak yeniden gözlemlenebilirden daha uzun süredir var oldu, bu yüzden kesinlikle önemli bir satış noktası. Daha fazla belge, örnek bulacaksınız ve muhtemelen destek alabileceğiniz daha iyi bir topluluğa sahip olacaksınız.

Buna karşılık, redux-saga'da öğrendiğiniz operatörlerin ve API'lerin neredeyse her yerde kullanılan RxJS'yi öğrenmek kadar aktarılabilir olmamasıdır. redux-observable dahili olarak süper süper süper basittir, gerçekten size RxJS'yi kullanmanız için doğal bir yol sunar. Dolayısıyla, RxJS'yi biliyorsanız (veya bilmek istiyorsanız), bu son derece doğal bir uyumdur.

Şu anda çoğu insan için tavsiyem, hangisini kullanmanız gerektiğini sormanız gerekiyorsa, muhtemelen redux-saga'yı seçmelisiniz.


9

Redux-Observable inanılmaz bir kitaplık, şu ana kadar herhangi bir sorun yaşamadan üretimde 1.5 yıldır kullanıyoruz, mükemmel bir şekilde test edilebilir ve herhangi bir çerçeveye kolayca entegre edilebilir. Aşırı derecede aşırı yüklenmiş paralel soket kanallarımız var ve bizi donmalardan kurtaran tek şey Redux-Observable.

Burada bahsetmek istediğim 3 noktam var.

1. Karmaşıklık ve öğrenme eğrisi

Redux-saga, burada redux-gözlemlenebilirliği kolayca yener. Yetkilendirmenin yapılması için basit bir isteğe ihtiyacınız varsa ve bazı nedenlerden dolayı redux-thunk kullanmak istemiyorsanız, redux-saga kullanmayı düşünmelisiniz, anlaşılması daha kolay.

Gözlemlenebilir hakkında önceden bilginiz yoksa bu sizin için acı olur ve ekibiniz sizi yönlendirir :)

2. Observable ve RxJS bana ne sunabilir?

Asenkron mantık söz konusu olduğunda Observable sizin İsviçre bıçağınızdır, Observable kelimenin tam anlamıyla sizin için neredeyse her şeyi yapabilir. Bunları asla vaatlerle veya jeneratörlerle karşılaştırmamalısınız, çok daha güçlüdür, Optimus Prime'ı Chevrolet ile karşılaştırmakla aynıdır.

Peki ya RxJS? Lodash.js gibidir, ancak zaman uyumsuz mantık için, bir kez girdiğinizde asla farklı bir şeye geçmeyeceksiniz.

3. Reaktif uzatma

Sadece bu bağlantıyı kontrol et

http://reactivex.io/languages.html

Reaktif uzantı, tüm modern programlama dilleri için uygulanmıştır, yalnızca işlevsel programlamanın anahtarıdır.

Bu yüzden zamanınızı akıllıca harcayarak RxJS öğrenin ve redux-observable kullanın :)


7

Rx'in sahip olduğu diller ve çalışma zamanları arasında aktarılabilirliğe değer veriyorum. Uygulamanız dil değiştirmeyecek olsa bile kariyeriniz değişebilir. Öğreniminizden en iyi şekilde yararlanın, ancak bunu kendiniz için boyutlandırın. Özellikle .Net LINQ için harika bir ağ geçidi.


2
Akıllı seçim, ancak jeneratörler de dilden bağımsızdır.
Greg Herbowicz

3

Burada bir sürü gözden geçirilebilir konuşma olduğundan, tartışmanın destan tarafını vermeyi düşündüm. Redux-observable veya RxJS kullanmıyorum, bu yüzden yan yana karşılaştırma yapamam, ancak sagaları harika bir etki için kullandım.

Değeri ne olursa olsun, bir web uygulamasında üretimde sagaları kullanıyorum.

Sagas ve Thunk

Saga eller aşağı kazanır. Aksiyon yaratıcılarıma mantığı nasıl yerleştirdiğini beğenmedim. Üst üste birkaç istekte bulunmayı da zahmetli hale getirdi. Bu iş için redux-observable'a kısaca baktım ama Sagas'a yerleştim.

Sagalar için Öğrenme Eğrisi

Jeneratörlerin ne olduğunu ve neden önemli olduklarını anlamak, destanları anlamanın anahtarıdır. Ancak jeneratörleri içten dışa bilmenize gerek olmadığını vurgulayacağım . Verim ifadesiyle kontrolü devre dışı bıraktığınızı ve asenkron kodunuz çözüldükten sonra destanın kontrolü geri vereceğini bilmeniz yeterlidir. Bundan sonra, bir destanda neler olduğunu anlamak o kadar da zor değil.

Temel destan yöntemleri (deneyimlerime göre):

  • call- Herhangi bir kod bitini çağırın ve dönüş değerini alın. Sözleri destekler. Eşzamansız işleme ve sagalar arasında büyük sinerji.
  • select- Bir seçici çağırın. Bu parça oldukça zekice. Seçiciler, yeniden düzenlenmenin temelidir ve% 100 desteklenirler!
  • put- aka dispatchbir eylem. Aslında istediğiniz kadar gönderin!

Başka işlevler de var, ancak bu üçünde ustalaşabilirseniz, gerçekten iyi bir noktada olacaksınız.

Sonuç

Sagaları seçmemin sebebi kullanım kolaylığıydı. redux-observable bir meydan okuma gibi görünüyordu. Destanlardan% 100 memnunum. Beklediğimden daha mutlu.

Tecrübelerime göre, Sagalar serserilerden (yol) daha iyidir ve anlaşılması nispeten kolaydır. Rx herkesin çayı değildir. Bu ekosistemden gelmezseniz ve / veya gelecekte Rx kullanmayı planlamıyorsanız, sagaları yeniden gözlemlenebilir olmak yerine kesinlikle düşünürüm.


2

Uygulamanızı Typescript'te yazarsanız , typeless'ı kontrol etmenizi öneririm . Redux-Observable'dan ilham alıyor ve ayrıca RxJS'ye bağlı, ancak uygulamayı oluşturmak için tüm ekosistem var.

Redux-observable / redux-saga'nın en büyük dezavantajları kılavuz eksikliğidir. Yük azaltıcıların, destanların veya destanların nasıl tembel olacağına dair resmi bir kılavuz yoktur. Daha büyük uygulamaları ölçeklendirirken kod bölme çok önemlidir. Geç yükleme için özel çözümler genellikle HMR ile çalışmaz ve geliştirici deneyiminin zayıf olmasına neden olur.

Tipsiz artılar:

  1. TypeScript
    için tasarlandı Tüm API'ler, typcript ve tür güvenliği için tasarlanmıştır:
    • Typcript, verimliliğinizi artıracak, sizi yavaşlatmayacak.
    • Yalnızca gerekli ek açıklamalar gereklidir: durum, eylem argümanları.
    • Tip dökümü yok. Her şey otomatik olarak çıkarılır. Kodun% 95'i saf javascript'e benziyor.
    • RootAction, RootEpic, RootState veya diğer yardımcı türleri yok.
  2. Tüm yapı taşlarını sağlayın
    • Typeless, orta ölçekli veya kurumsal düzeyde uygulamalar oluşturmak için her şeyi içerir.
    • Birden çok küçük kitaplığa güvenmenize gerek yok.
  3. Modülarite
    • Ölçeklenebilir uygulamalar oluşturmak için uygun modülerlik çok önemlidir.
    • Destanlar, indirgeyiciler, türler, vb. İçin kök dosyalar oluşturmanıza gerek yoktur. Yeni bir modül oluşturduğunuzda, onu herhangi bir yerden ekleyebilirsiniz. Standart React bileşenlerine benzer.
  4. inatçı
    • Tüm yaygın kullanım durumları ve sorunları varsayılan olarak çözülür. Önemsiz sorunları nasıl çözeceğinizi fazla düşünmeye gerek yok.
    • Tüm öneriler ve en iyi uygulamalar sağlanır!

Https://typeless.js.org/ adresine göz atın


1
Birincil katkı sağlayıcısı olduğunuz yazılımı önerirken bir sorumluluk reddi beyanı eklemelisiniz.
Hagelt18
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.