Skip to content

Instantly share code, notes, and snippets.

@pastelmind
Last active July 14, 2022 08:22
Show Gist options
  • Save pastelmind/10330b1303ac116d8746a56476c945c8 to your computer and use it in GitHub Desktop.
Save pastelmind/10330b1303ac116d8746a56476c945c8 to your computer and use it in GitHub Desktop.
To use observable or plain JS?

StoreItem 클래스에는 두 개의 값(amount, status)이 있습니다. 한 값을 변경했을 때 다른 값을 함께 변경하고 싶다면 어떻게 하는 게 좋을까요?

  • StoreItemA: setAmount() 내에서 변경한다
  • StoreItemB: Observable을 사용해서 업데이트하자
import { BehaviorSubject, filter, switchMap, tap, withLatestFrom } from "rxjs";
enum Status {
NO_SALE = "NO_SALE",
SALE = "SALE"
}
// 규칙: amount를 0 이하로 변경하면 status를 NO_SALE로 바꿔야 한다
// 규칙: status를 SALE로 변경할 때 amount가 0 이하이면 1로 바꿔야 한다
abstract class StoreItemBase {
protected _statusSubject = new BehaviorSubject(Status.NO_SALE);
protected _amountSubject = new BehaviorSubject(0);
get status$() {
return this._statusSubject.asObservable();
}
get amount$() {
return this._amountSubject.asObservable();
}
abstract setStatus(status: Status): void;
abstract setAmount(amount: number): void;
}
// 규칙 체크를 setAmount(), setStatus() 내에서 수행
class StoreItemA extends StoreItemBase {
setStatus(status: Status) {
this._statusSubject.next(status);
if (status === Status.SALE && this._amountSubject.value <= 0) {
this._amountSubject.next(1);
}
}
setAmount(amount: number) {
this._amountSubject.next(amount);
if (amount <= 0) {
this._statusSubject.next(Status.NO_SALE);
}
}
}
// 조건 체크를 observable 내에서 수행
class StoreItemB extends StoreItemBase {
constructor() {
super();
this.amount$.pipe(
filter((amount) => amount <= 0),
tap(() => this.setStatus(Status.NO_SALE))
).subscribe();
this.status$.pipe(
filter((status) => status === Status.SALE),
withLatestFrom(this.amount$),
filter(([, amount]) => amount <= 0),
tap(() => this.setAmount(1))
).subscribe();
}
setStatus(status: Status) {
this._statusSubject.next(status);
}
setAmount(amount: number) {
this._amountSubject.next(amount);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment