【问题标题】:In what cases take operator is actually used?在什么情况下实际使用了 take 运算符?
【发布时间】:2020-02-04 14:40:08
【问题描述】:

我想了解为什么在下面给出的代码中使用take 运算符。

private _places = new BehaviorSubject<Place[]>(
// places for initialization
);

get places() {
  return this._places.asObservable();
}

addPlace(title: string, description: string, price: number)
{
    generatedId: string;
    newPlace: Place;
    // code to initialize newPlace
    return this.http.post<{name: string}>(
        'https://ionic-angular-ef2f8.firebaseio.com/offered-places.json', 
        {...newPlace, id: null})
        .pipe(
          switchMap(response => {
            generatedId = response.name;
            return this.places;
          }),
          take(1),
          tap(places => {
            newPlace.id = generatedId;
            this._places.next(places.concat(newPlace));
          })
        );
}

post 请求返回一个Observable,我们在switchMap 运算符中从中获取一个值(注意,在调用switchMap 之前我们没有take 一个值)。在switchMap 中,我们将可观察对象替换为从_places 获得的新可观察对象,即BehaviourSubject 对象。在switchMap 之后,我们使用take 运算符。 为什么我们不跳过take 运算符,直接使用tap?我们是否take 来自可观察对象的值,因为可观察对象是从主题生成的?谁能详细解释take操作符的用例?

更新

我怀疑我应该在switchMap 之后使用take 运算符的原因是switchMap 返回一个从BehaviorSubject 类型的对象接收到的可观察对象,该对象包含发出的值。可以订阅这样的 BehaviorSubject 对象和 take 最新发出的值 - 这正是我所做的。

【问题讨论】:

    标签: rxjs


    【解决方案1】:

    httpClient.post() 发出一个next 通知和一个complete 通知。

    但是,他们使用switchMap 将另一个 Observable 合并到链中 (this.places)。 switchMap() 将在其源和内部 Observable 完成之前完成,因此他们使用 take(1)this.places 的第一次发射后完成链,这是一个 BehaviorSubject 直到你故意调用才会完成complete() 就可以了。

    这是一个与使用takeUntil() 完成链非常相似的用例。 takeUntil() 总是必须是链中的最后一个运算符,因为完成 switchMap()concatMap()、... 的源 Observable 不一定完成整个链。更多详情请参见https://medium.com/angular-in-depth/rxjs-avoiding-takeuntil-leaks-fb5182d047ef

    【讨论】:

    • 我知道 switchMap 用新的 observable 替换了以前的 observable(它不合并)。我怀疑第一个 observable(从 this.http.post 收到)在 switchMap 工作后完成。
    • 我问了这个问题,因为没有take(1) 运算符,这段代码就无法工作。我不知道为什么。 (我在调用addPlace方法的代码中取消订阅tap返回的observable)
    • 那么调用 addPlace() 的人可能依赖于它的完整处理程序
    • 不,它不依赖它,它在其组件被销毁时取消订阅(我在那里使用takeUntil)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-10
    • 1970-01-01
    • 1970-01-01
    • 2019-08-08
    • 2015-11-14
    • 1970-01-01
    相关资源
    最近更新 更多