2012-01-11 30 views
8

Tôi đang học về phản ứng chuối và dự định sử dụng nó trong ứng dụng phía máy chủ. Tôi có một số nền tảng trong RxJs, vì vậy tôi đã sử dụng để kết hợp Sự kiện với các tổ hợp khác nhau ở đó. Vì vậy, tôi bắt đầu với các ví dụ tổ hợp sự kiện đơn giản. Tôi đã cố gắng tạo ra một ví dụ phản ứng chuối đơn giản có thể kết hợp hai sự kiện số nguyên thành một sự kiện tổng hợp. Tôi hiểu rằng để có thể kết hợp các giá trị từ các sự kiện khác nhau, trước tiên tôi phải biến chúng thành Hành vi, thực hiện kết hợp và cuối cùng biến nó thành một sự kiện mới. Đây là cách tôi đã thực hiện:Có gì sai với "sự kiện tổng hợp" của tôi trong chuối phản ứng?

-- Behaviors from Events e1, e2 
let b1 = stepper 0 e1 :: Behavior Int 
let b2 = stepper 0 e2 :: Behavior Int 

-- Sum Behavior 
let sumB = (+) <$> b1 <*> b2 
-- Back to Event 
let sumE = sumB <@ (e1 `union` e2) 

Ví dụ có thể chạy đầy đủ có thể được tìm thấy trong Gist 1594917.

Vấn đề ở đây là khi sự kiện sumE được kích hoạt chính xác khi giá trị mới xuất hiện trong một trong các sự kiện (e1, e2), nó chứa giá trị cũ. Điều này rõ ràng là do làm thế nào stepper hoạt động (giá trị của hành vi thay đổi "hơi sau" sự kiện xảy ra). Tôi đã thử thay thế Hành vi bằng Rời rời, với cùng một kết quả.

Có cách nào đơn giản để làm cho loại tổ hợp sự kiện này hoạt động chính xác không?

Trả lời

6

Chẩn đoán của bạn là chính xác. Dưới đây là hai tùy chọn: bạn có thể quay lại Sự kiện từ Rời khỏi changes hoặc bạn có thể tạo các sự kiện tích lũy.

Làm việc lại từ Rời rời có lẽ đơn giản hơn (và là những gì tôi muốn giới thiệu). Chỉ cần làm

-- Discretes from Events e1, e2 
let d1 = stepperD 0 e1 :: Discrete Int 
let d2 = stepperD 0 e2 :: Discrete Int 

-- Sum Discrete 
let sumD = (+) <$> d1 <*> d2 
-- Back to Event 
let sumE = changes sumD 

Bây giờ sumE sẽ luôn cập nhật khi e1 hoặc e2 thay đổi.

Chỉ sử dụng thay thế Sự kiện, bằng cách chuyển đổi sự kiện đến thành chức năng tích lũy. Nghe có vẻ phức tạp, nhưng mã này khá đơn giản.

--convert each input into an accumulating tuple 
let e1' = (\l (_,r) -> (l,r)) <$> e1 
let e2' = (\r (l,_) -> (l,r)) <$> e2 

let sumE = uncurry (+) <$> accumE (0,0) (e1' `union` e2') 
+0

Chỉ cần làm rõ: không có sự chậm trễ trong một trong hai cách tiếp cận của bạn, các sự kiện 'sumE' sẽ xảy ra đồng thời với' e1' và 'e2'. –

+0

Cảm ơn, @HeinrichApfelmus. Tôi đã chỉnh sửa câu trả lời của tôi để hy vọng rõ ràng hơn. –

+0

cảm ơn các bạn! nó hoạt dộng bây giờ. – raimohanska

Các vấn đề liên quan