2017-06-19 27 views
8

Tôi có một đường ống RxJS5 trông như thế nàyRxJS takeWhile nhưng bao gồm giá trị cuối cùng

Rx.Observable.from([2, 3, 4, 5, 6]) 
    .takeWhile((v) => { v !== 4 }) 

tôi muốn giữ đăng ký cho đến khi tôi thấy 4, nhưng tôi muốn yếu tố cuối cùng 4 cũng được bao gồm trong kết quả . Vì vậy, ví dụ trên nên

2, 3, 4 

Tuy nhiên, theo official document, takeWhile điều hành không phải là toàn diện. Điều đó có nghĩa là khi nó gặp phần tử không khớp với biến vị ngữ mà chúng tôi đã cung cấp, nó hoàn thành luồng ngay lập tức mà không có phần tử cuối cùng. Kết quả là, các mã trên sẽ thực sự ra

2, 3 

Vì vậy, câu hỏi của tôi là, cách dễ nhất tôi có thể đạt được takeWhile mà còn phát ra yếu tố cuối cùng với RxJS là gì?

+0

Hơi phô trương, nhưng cách dễ nhất sẽ là '.takeWhile (v => v <5) ' – cartant

+0

Nghiêm trọng hơn: https://github.com/martinsik/rxjs-extra/blob/master/src/operator/takeWhileInclusive.ts – cartant

Trả lời

11

Như vậy là ít nhất hai cách giải quyết có thể:

  1. sử dụng concatMap():

    Observable.of('red', 'blue', 'green', 'orange') 
        .concatMap(color => { 
        if (color === 'green') { 
         return Observable.of(color, null); 
        } 
        return Observable.of(color); 
        }) 
        .takeWhile(color => color) 
        .subscribe(color => console.log(color)); 
    
  2. Sử dụng multicast():

    Observable 
        .of("red", "blue", "green", "orange") 
        .multicast(
        () => new ReplaySubject(1), 
        (colors) => colors.takeWhile((c) => c !== 'green').concat(colors.take(1)) 
    ) 
    

Tôi đã sử dụng toán tử này cũng vì vậy tôi đã làm cho nó để thiết lập riêng của tôi về RxJS thêm 5 nhà khai thác: https://github.com/martinsik/rxjs-extra#takewhileinclusive

Toán tử này cũng đã được thảo luận trong các vấn đề RxJS 5: https://github.com/ReactiveX/rxjs/issues/2420

3

Nếu so sánh của bạn là như vậy mà bạn biết chính xác những gì là yếu tố cuối cùng (như cho !==), bạn có thể thêm lại tự hỏi:

Rx.Observable.from([2, 3, 4, 5, 6]) 
    .takeWhile((v) => v !== 4) 
    .concat(Rx.Observable.of(4)) 
    .subscribe(console.log) 
0

tôi đi qua cùng một vấn đề, tôi cần yếu tố cuối cùng để được bao gồm vì vậy tôi đã chọn để giữ một tham chiếu đến các thuê bao và hủy đăng ký trong sốonNextgọi lại khi điều kiện được đáp ứng. Sử dụng mã ví dụ của bạn, nó sẽ là:

const subscription = Observable.of('red', 'blue', 'green', 'orange') 
    .subscribe(color => { 
    // Do something with the value here 
    if (color === 'green') { 
     subscription.unsubscribe() 
    } 
    }) 

Điều này làm cho tôi vì nó cũng khiến nguồn có thể quan sát ngừng phát ra là những gì tôi cần trong kịch bản của mình. Tôi nhận thấy rằng tôi không sử dụng toán tử takeWhile nhưng mục tiêu chính là đạt được và không có bất kỳ cách giải quyết hoặc mã bổ sung nào. Tôi không phải là một fan hâm mộ buộc phải làm việc theo cách mà họ không được thiết kế. Những bất lợi của việc này là:

  • Nếu có bất kỳ người quan sát nào khác đăng ký, nguồn sẽ tiếp tục phát ra.
  • onCompleted không được gọi vì một lý do nào đó nếu người quan sát cuối cùng hủy đăng ký, nhưng tôi đã kiểm tra xem nguồn trên thực tế có dừng phát hay không.
Các vấn đề liên quan