Tại sao nên sử dụng Redux-Observable trên Redux-Saga?


133

Tôi đã sử dụng Redux-Saga . Mã được viết với nó rất dễ để lập luận cho đến nay, ngoại trừ chức năng trình tạo JS thỉnh thoảng làm tôi rối tung lên. Theo hiểu biết của tôi, Redux-Observable có thể đạt được công việc tương tự xử lý các tác dụng phụ nhưng không sử dụng chức năng của trình tạo.

Tuy nhiên, các tài liệu từ Redux-Observable không cung cấp nhiều ý kiến ​​về lý do tại sao nó vượt trội so với Redux-Saga. Tôi muốn biết liệu không sử dụng chức năng của trình tạo có phải là lợi ích duy nhất của việc sử dụng Redux-Observable hay không. Và những gì có thể là nhược điểm, gotcha hoặc thỏa hiệp từ việc sử dụng Redux-Observable thay vì Redux-Saga? Cảm ơn trước.


Tôi đã thực hiện một blog thú vị nhưng chi tiết, nơi tôi thấy Redux-Saga vượt trội hơn Redux-Observable cho những người không sống / ăn / thở có thể quan sát cả ngày. Tôi chắc chắn sẽ rất tuyệt nếu toàn bộ ngăn xếp của bạn có thể quan sát được. shift.infinite.red/ Kẻ
Gant Laborde

Câu trả lời:


236

Tuyên bố miễn trừ trách nhiệm: Tôi là một trong những tác giả của redux - có thể quan sát được nên tôi khó có thể vô tư 100%.

Hiện tại chúng tôi không cung cấp bất kỳ lý do nào có thể quan sát được redux tốt hơn redux-saga bởi vì ... không phải vậy. 😆

tl; dr có những ưu và nhược điểm cho cả hai. Nhiều người sẽ tìm thấy một thứ trực quan hơn cái kia, nhưng cả hai đều phức tạp để học theo những cách khác nhau nếu bạn không biết RxJS (có thể quan sát được) hoặc trình tạo / "hiệu ứng như dữ liệu" (redux-saga).

Họ giải quyết cùng một vấn đề theo những cách cực kỳ giống nhau, nhưng có một số khác biệt cơ bản chỉ trở nên thực sự rõ ràng khi bạn sử dụng chúng đủ.

redux có thể quan sát được gần như tất cả mọi thứ đối với RxJS thành ngữ. Vì vậy, nếu bạn có kiến ​​thức RxJS (hoặc có được nó), việc học và sử dụng redux có thể quan sát là siêu siêu tự nhiên. Điều đó cũng có nghĩa là kiến ​​thức này có thể chuyển sang những thứ khác ngoài redux. Nếu bạn quyết định chuyển sang MobX, nếu bạn quyết định chuyển sang Angular2, nếu bạn quyết định chuyển sang một số độ hot X trong tương lai, rất có thể RxJS có thể giúp bạn. Điều này là do RxJS là một thư viện async chung, và theo nhiều cách, nó giống như một ngôn ngữ lập trình trong chính bản thân nó trong toàn bộ mô hình "Lập trình phản ứng". RxJS tồn tại từ năm 2012 và bắt đầu như một cổng của Rx.NET (có "cổng" trong gần như mọi ngôn ngữ chính, nó rất hữu ích ).

redux-saga cung cấp chính các toán tử dựa trên thời gian của nó, vì vậy trong khi kiến ​​thức bạn có được về các trình tạo và xử lý các tác dụng phụ theo kiểu trình quản lý quy trình này có thể chuyển được, thì các toán tử và cách sử dụng thực tế không được sử dụng trong bất kỳ thư viện chính nào khác. Vì vậy, đó là một chút đáng tiếc, nhưng chắc chắn không nên là một người phá vỡ thỏa thuận.

Nó cũng sử dụng "hiệu ứng như dữ liệu" ( được mô tả ở đây ), có thể khó khăn trong việc quấn đầu của bạn, nhưng điều đó có nghĩa là mã redux-saga của bạn không thực sự tự thực hiện các tác dụng phụ. Thay vào đó, các hàm trợ giúp bạn sử dụng tạo các đối tượng giống như các tác vụ thể hiện ý định thực hiện hiệu ứng phụ và sau đó thư viện nội bộ thực hiện nó cho bạn. Điều này làm cho việc kiểm tra cực kỳ dễ dàng, không cần phải chế giễu và rất hấp dẫn đối với một số người. Tuy nhiên, cá nhân tôi đã nhận thấy điều đó có nghĩa là các bài kiểm tra đơn vị của bạn thực hiện lại phần lớn logic của câu chuyện của bạn - làm cho các bài kiểm tra đó không hữu ích IMO (ý kiến ​​này không được mọi người chia sẻ)

Mọi người thường hỏi tại sao chúng ta không làm điều gì đó như thế với redux có thể quan sát được: với tôi về cơ bản nó không tương thích với Rx thành ngữ bình thường. Trong Rx, chúng tôi sử dụng các toán tử như thế .debounceTime()gói gọn logic cần thiết để gỡ lỗi, nhưng điều đó có nghĩa là nếu chúng tôi muốn tạo một phiên bản của nó mà không thực sự thực hiện việc gỡ lỗi và thay vào đó phát ra các đối tượng tác vụ với ý định, giờ bạn đã mất sức mạnh của Rx bởi vì bạn không thể chỉ vận hành chuỗi nữa vì chúng sẽ hoạt động trên đối tượng tác vụ đó, không phải là kết quả thực sự của hoạt động. Điều này thực sự khó để giải thích một cách thanh lịch. Nó một lần nữa đòi hỏi sự hiểu biết nặng nề về Rx để hiểu sự không tương thích của các phương pháp. Nếu bạn thực sự muốn một cái gì đó như thế, hãy kiểm tra chu kỳ reduxtrong đó sử dụng cycl.js và hầu hết có các mục tiêu đó. Tôi thấy nó đòi hỏi quá nhiều nghi lễ cho thị hiếu của tôi, nhưng tôi khuyến khích bạn hãy cho nó một vòng quay nếu nó làm bạn hứng thú.

Như ThorbenA đã đề cập, tôi không ngại thừa nhận rằng redux-saga hiện tại (10/13/16) là nhà lãnh đạo rõ ràng trong quản lý hiệu ứng phụ phức tạp cho redux. Nó đã được bắt đầu sớm hơn và có một cộng đồng mạnh mẽ hơn. Vì vậy, có rất nhiều sự hấp dẫn để sử dụng tiêu chuẩn thực tế so với đứa trẻ mới trong khối. Tôi nghĩ thật an toàn nếu bạn sử dụng mà không có kiến ​​thức trước, bạn sẽ gặp một số nhầm lẫn. Cả hai chúng tôi đều sử dụng các khái niệm khá tiên tiến mà một khi bạn "có được", việc quản lý hiệu ứng phụ phức tạp trở nên dễ dàng hơn rất nhiều, nhưng cho đến lúc đó nhiều vấp ngã.

Lời khuyên quan trọng nhất tôi có thể đưa ra là đừng mang vào một trong những thư viện này trước khi bạn cần chúng. Nếu bạn chỉ thực hiện các cuộc gọi ajax đơn giản, có lẽ bạn không cần chúng. redux-thunk thật đơn giản để học và cung cấp đủ cho những điều cơ bản - nhưng càng không đồng bộ thì càng khó (hoặc thậm chí là không thể), nó trở nên khó khăn hơn cho redux-thunk. Nhưng đối với redux-obsable / saga theo nhiều cách, nó tỏa sáng nhất là async phức tạp hơn. Cũng có rất nhiều công đức trong việc sử dụng redux-thunk với một trong những người khác (redux-obsable / saga) trong cùng một dự án! redux-thunk cho những thứ đơn giản phổ biến của bạn và sau đó chỉ sử dụng redux-obsable / saga cho những thứ phức tạp. Đó là một cách tuyệt vời để duy trì hiệu quả, vì vậy bạn không phải chiến đấu với redux-obsable / saga cho những thứ tầm thường với redux-thunk.


3
Chỉ cần nhìn thấy cuộc nói chuyện của bạn (uuhf âm thanh!), Và ngay lập tức nhấn + T + "redux-saga vs redux-obsable". Tôi đã sử dụng redux-saga khá lâu rồi (đặc biệt là trong React Native), nhưng sau khi xem bài nói chuyện của bạn và bài đăng này tôi có thể thấy một số trường hợp sử dụng (đối với tôi) trong đó redux-obs. sẽ thực sự là một phù hợp tốt hơn. Ví dụ của bạn về debounceTime()và đã "mất" quyền kiểm soát đối với một loại logic rất chung chung đã tạo ra nó cho tôi. Cảm ơn vì đã giải thích.
Hulvej

3
Chỉ cần nhìn thấy cuộc nói chuyện là tốt và làm một chút googling xung quanh. Thứ tốt @jayphelps, cảm ơn vì đã chia sẻ. Tôi đặc biệt thích nhận xét của bạn xung quanh việc sử dụng redux-thunk kết hợp với redux-obsable / saga. Điều đó rất có ý nghĩa, tại sao lại quá phức tạp các yêu cầu AJAX đơn giản khi không cần thiết. Điều đó nói rằng, có một cái gì đó để nói về tính đồng nhất và giữ cho mọi người nhất quán. Cảm ơn một lần nữa!
Spets

Trước khi nâng cấp lên Redux-saga / Redux-quan sát, bạn có thể thử Redux-dispatch-nghe và đó là rất đơn giản và đã có thể giải quyết một số usecases của bạn: github.com/slorber/redux-dispatch-subscribe
Sebastien Lorber

Đây là một câu trả lời rất hữu ích. Cảm ơn bạn! Tôi thích quan điểm về việc có thể chuyển kiến ​​thức về RxJS sang các miền / khung khác.
Anselan

@jayphelps Điều gì sẽ là một ví dụ về "async phức tạp". Hiện đang cố gắng đánh giá thời tiết tôi nên chuyển từ thunk sang saga / obsables cho một dự án. Cảm ơn :)
Sam Bokai

64

Tôi nghĩ rằng có những điều mà bạn cần phải xem xét.

  1. Phức tạp
  2. Kiểu mã hóa
  3. Đường cong học tập
  4. Khả năng kiểm tra

Hãy nói rằng chúng tôi muốn tìm nạp người dùng từ 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'})
        )

Ngoài ra, tôi đã viết bài viết này để so sánh sự khác biệt giữa Redux-saga và Redux-Observable theo chiều sâu. Kiểm tra liên kết này ở đây hoặc trình bày .


3
sự so sánh song song này từ liên kết là rất tốt, cảm ơn
rofrol

1
Tôi thích sự so sánh, NHƯNG có một vấn đề với nó tôi muốn đưa lên. Khi bạn so sánh chúng bằng các cuộc gọi api - bạn đang sử dụng tìm nạp để có thể quan sát được. mát mẻ. NHƯNG, khi bạn hiển thị sự khác biệt "có thể hủy" .. bạn KHÔNG sử dụng tìm nạp - thay vào đó bạn sử dụng Observable.ajax bên trong ... tại sao? Tôi muốn giữ nó bằng cách sử dụng "tìm nạp" hoặc "axios". nếu không, công việc tuyệt vời ở đó.
james emanon

5
@jamesemanon Tôi cho rằng anh ta không sử dụng tìm nạp vì API tìm nạp chưa có tùy chọn để hủy. (thêm về điều này: github.com/whatwg/fetch/issues/27 )
Daniel Andrei

Wow, so sánh sâu với tất cả các ví dụ là tốt nhất. Cảm ơn bạn!
Radek Matěj

22

Tôi sử dụng Redux-Observable trên Redux-Saga vì thích làm việc với các đài quan sát hơn máy phát điện. Tôi sử dụng nó với RXJS, một thư viện mạnh mẽ để làm việc với các luồng dữ liệu. Hãy nghĩ về nó như lodash cho async. Xét về bất kỳ nhược điểm nào, gotcha và thỏa hiệp trong việc lựa chọn cái này, hãy xem câu trả lời này từ Jay Phelps:

redux-saga như một dự án đã tồn tại lâu hơn redux có thể quan sát được, vì vậy đó chắc chắn là một điểm bán hàng chính. Bạn sẽ tìm thấy nhiều tài liệu, ví dụ và có khả năng có một cộng đồng tốt hơn để nhận được hỗ trợ.

Đối trọng là các toán tử và API bạn học trong redux-saga gần như không thể chuyển nhượng được như học RxJS, được sử dụng ở mọi nơi. redux-obsable là siêu siêu siêu đơn giản trong nội bộ, nó thực sự chỉ mang đến cho bạn một cách tự nhiên để bạn sử dụng RxJS. Vì vậy, nếu bạn biết RxJS (hoặc muốn), đó là một sự phù hợp cực kỳ tự nhiên.

Lời khuyên của tôi tại thời điểm này đối với hầu hết mọi người là nếu bạn phải hỏi bạn nên sử dụng cái nào, có lẽ bạn nên chọn redux-saga.


9

Redux-Observable là một thư viện tuyệt vời, chúng tôi sử dụng nó trong sản xuất trong 1,5 năm mà không có vấn đề gì cho đến nay, nó hoàn toàn có thể kiểm tra và có thể dễ dàng tích hợp với bất kỳ khuôn khổ nào. Chúng tôi đang có các kênh ổ cắm song song cực kỳ quá tải và điều duy nhất cứu chúng tôi khỏi bị đóng băng là Redux-Observable

Tôi có 3 điểm tôi muốn đề cập ở đây.

1. Độ phức tạp và đường cong học tập

Redux-saga dễ dàng đánh bại redux có thể quan sát ở đây. Nếu bạn chỉ cần một yêu cầu đơn giản để thực hiện ủy quyền và bạn không muốn sử dụng redux-thunk vì một số lý do, bạn nên xem xét sử dụng redux-saga, điều đó dễ hiểu hơn.

Nếu bạn không có kiến ​​thức trước về Quan sát, đó sẽ là một nỗi đau cho bạn và nhóm của bạn sẽ theo bạn :)

2. Những gì có thể quan sát và RxJS cung cấp cho tôi?

Khi nói đến logic không đồng bộ, Observable là con dao Thụy Sĩ của bạn, Observable có thể thực hiện hầu hết mọi thứ cho bạn. Bạn không bao giờ nên so sánh chúng với những lời hứa hoặc máy phát điện mạnh hơn nhiều, nó giống như so sánh Optimus Prime với Chevrolet.

Còn RxJS thì sao? Nó giống như lodash.js nhưng đối với logic async, một khi bạn vào, bạn sẽ không bao giờ chuyển sang thứ gì đó khác.

3. Mở rộng phản ứng

Chỉ cần kiểm tra liên kết này

http://reactivex.io/lacular.html

Phần mở rộng phản ứng được triển khai cho tất cả các ngôn ngữ lập trình hiện đại, đó chỉ là chìa khóa của bạn để lập trình chức năng.

Vì vậy, hãy dành thời gian của bạn một cách khôn ngoan để học RxJS và sử dụng redux-obsable :)


7

Tôi đánh giá khả năng chuyển đổi giữa các ngôn ngữ và thời gian chạy mà Rx có. Ngay cả khi ứng dụng của bạn không thay đổi ngôn ngữ, sự nghiệp của bạn có thể. Có được đòn bẩy tốt nhất bạn có thể cho việc học của mình, tuy nhiên bạn tăng kích thước đó cho chính mình. Đó là một cổng thông tin tuyệt vời đến .Net LINQ nói riêng.


2
Lựa chọn thông minh, mặc dù máy phát điện cũng không biết ngôn ngữ.
Greg Herbowicz

3

Vì có cả đống cuộc nói chuyện có thể quan sát được ở đây, tôi nghĩ tôi sẽ đưa ra khía cạnh của cuộc tranh luận. Tôi không sử dụng RuxJS có thể quan sát được hoặc RuxJS, vì vậy tôi không thể đưa ra so sánh cạnh nhau, nhưng tôi đã sử dụng sagas để có hiệu quả tuyệt vời.

Để biết giá trị của nó, tôi đang sử dụng sagas trong sản xuất trong một ứng dụng web.

Sagas vs Thunk

Saga thắng tay. Tôi không thích cách mà thunk đưa logic vào những người sáng tạo hành động của tôi. Nó cũng làm cho một vài yêu cầu liên tiếp trở nên rắc rối. Tôi thoáng nhìn vào redux - có thể quan sát được cho công việc này, nhưng đã giải quyết được Sagas.

Học đường cong cho Sagas

Hiểu máy phát điện là gì và tại sao chúng quan trọng là chìa khóa để hiểu sagas. Nhưng tôi sẽ nhấn mạnh rằng bạn không cần phải biết máy phát điện từ trong ra ngoài. Bạn chỉ cần biết rằng bạn đang mất kiểm soát với câu lệnh lợi nhuận và câu chuyện sẽ trả lại quyền kiểm soát sau khi mã async của bạn được giải quyết. Sau đó, không khó để hiểu chuyện gì đang xảy ra trong một câu chuyện.

Các phương pháp saga cốt lõi là (theo kinh nghiệm của tôi):

  • call- Gọi bất kỳ bit mã nào và nhận giá trị trả về. Hỗ trợ lời hứa. Sức mạnh tổng hợp tuyệt vời giữa xử lý async và sagas.
  • select- Gọi một bộ chọn. Bit này là khá rực rỡ. Bộ chọn là cốt lõi để chuyển hướng, và chúng được hỗ trợ 100%!
  • put- aka dispatchmột hành động. Trong thực tế gửi nhiều như bạn muốn!

Có các chức năng khác, nhưng nếu bạn có thể thành thạo ba điều đó, bạn sẽ ở một vị trí thực sự tốt.

Phần kết luận

Lý do tôi chọn sagas là dễ sử dụng. redux-obsable trông giống như một thách thức. Tôi hài lòng 100% với sagas. Hạnh phúc hơn tôi mong đợi.

Theo kinh nghiệm của tôi, Sagas (cách) tốt hơn thunks và tương đối dễ hiểu. Rx không phải là tách trà của mọi người. Tôi sẽ cân nhắc mạnh mẽ về sagas thay vì có thể quan sát được nếu bạn không đến từ hệ sinh thái đó và / hoặc không có kế hoạch sử dụng Rx trong tương lai.


2

Nếu bạn viết ứng dụng của bạn trong Bản in, tôi khuyên bạn nên kiểm tra không đánh máy . Nó lấy cảm hứng từ Redux-Observable, và cũng phụ thuộc vào RxJS, nhưng có toàn bộ hệ sinh thái để xây dựng ứng dụng.

Nhược điểm lớn nhất của redux-obsable / redux-saga là thiếu hướng dẫn. Không có hướng dẫn chính thức về cách lười biếng giảm tải, sagas hoặc sử thi. Chia tách mã là rất quan trọng khi nhân rộng các ứng dụng lớn hơn. Các giải pháp tùy chỉnh cho việc tải lười biếng thường không hoạt động với HMR gây ra trải nghiệm nhà phát triển kém.

Ưu điểm không tên:

  1. Được thiết kế cho TypeScript
    Tất cả các API được thiết kế cho kiểu chữ và an toàn kiểu:
    • Bản đánh máy sẽ tăng năng suất của bạn, không làm bạn chậm lại.
    • Chỉ các chú thích cần thiết là bắt buộc: trạng thái, đối số hành động.
    • Không đánh máy. Mọi thứ đều được suy luận tự động. 95% mã trông giống như javascript thuần túy.
    • Không có RootAction, RootEpic, RootState hoặc các loại trình trợ giúp khác.
  2. Cung cấp tất cả các khối xây dựng
    • Không chữ bao gồm mọi thứ để xây dựng các ứng dụng cỡ trung bình hoặc doanh nghiệp.
    • Bạn không cần phải dựa vào nhiều thư viện nhỏ.
  3. Tính mô đun
    • Mô-đun thích hợp là rất quan trọng để xây dựng các ứng dụng có thể mở rộng.
    • Không cần phải tạo tập tin gốc cho sử thi, bộ giảm tốc, loại, v.v. Khi bạn tạo một mô-đun mới, bạn có thể đính kèm nó từ bất kỳ nơi nào. Tương tự như các thành phần React tiêu chuẩn.
  4. Khăng khăng
    • Tất cả các trường hợp sử dụng phổ biến và các vấn đề được giải quyết theo mặc định. Không cần phải suy nghĩ quá nhiều làm thế nào để khắc phục các vấn đề tầm thường.
    • Tất cả các khuyến nghị và thực hành tốt nhất được cung cấp!

Hãy xem https://typless.js.org/


1
Bạn nên thêm từ chối trách nhiệm khi giới thiệu phần mềm mà bạn là người đóng góp chính.
Hagelt18
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.