在Angular中使用同步管道时如何手动停止Observer

时间:2018-08-02 19:18:12

标签: angular rxjs angular-pipe angular-observable

让我们编写一个简单的示例,该示例每1秒递增一次,用户| sync将更新模板:

@Component({
  selector: 'my-counter',
  templateUrl: '
      </div> {{time | async}}</div>
      <button (click)="stop()"> stop counter</button>'
  })
export class AppComponent implements OnInit {
  counter: Observable<any>;

  ngOnInit() {
    this.counter = interval(1000).pipe(
      map(i => `Result ${i}`)
    );
  }

  stop() {
    this.counter.unsubscribe(); // error. no such thing unsubscribe()
  }

  activate() {
   this.counter /// ??? 
  }
}

但是现在模板通过Subscription方法获得了unsubscribe值的处理程序。

那我该如何停止柜台?

在我停止它之后,有一种方法可以再次激活?

3 个答案:

答案 0 :(得分:2)

您可以使用takeUntil运算符,该运算符将监听第二个Observable,并在听到事件时取消订阅。例如,在下面的代码中,我们创建一个名为Subject的{​​{1}}。只要我们在stop$上发出一个值,我们的订阅就会结束

stop$

Here is a StackBlitz demo

答案 1 :(得分:1)

在Rx中,当您订阅任何可观察项时,您将获得一次性订阅: 这是可观察的基本契约:

Observable<T>.subscribe(observer: Observer<T>) : Subscription

在您的示例中,counter不是订阅,它本身是可观察的。

如果要基于外部条件终止可观察对象,则可以使用诸如takeUntiltakeWhile之类的限制运算符来完成可观察序列。当可观察对象完成或引发错误时,将处理所有订阅。

要创建可以从外部触发的计时器:

let startStop = new Rx.Subject()

let counter = 
    startStop
    .startWith(false)
    .switchMap(v => v ? Rx.Observable.interval(1000) : Rx.Observable.empty())
    .select((_, i) => i) 

counter.subscribe(x => console.log(x)) //print

//start timer
startStop.onNext(true)

//stop timer
startStop.onNext(false)

答案 2 :(得分:0)

我尝试使用不同的方法,而不是使用Observer来使用Subject

  @Component({
    selector: 'my-counter',
    templateUrl: `
      </div> {{time | async}}</div>
      <button (click)="stop()"> stop counter</button>
    `
  })
  export class MyCounter implements OnInit {
    counter: Subject<any>;
    value = 0;

    ngOnInit() {
      this.counter = new Subject();
      setInterval(_ => {
        this.counter.next( this.value++ );
      },1000);
    }

    stop() {
      this.counter.unsubscribe(); // work now
    }

    activate() {
      this.counter /// ??? 
    }
  }