Skip to content

Latest commit

 

History

History
191 lines (141 loc) · 6.61 KB

File metadata and controls

191 lines (141 loc) · 6.61 KB

생성 함수

create 함수

create 함수는 옵저버블이 어떤 작업을 할지 정의해 생성한다. Observable 클래스에 속해 있는 기본 함수이기도 하다.

함수 원형은 다음과 같다.

static create: Function

Observable 생성자를 호출하여 새로운 콜드 옵저버블을 작성한다. 인자로 사용하는 3개 함수인 next, error, complete를 호출할 수 있다. 3개 함수는 옵저버블을 구독할 때 호출하며, 옵저버로 전달되는 값을 구독하는 쪽 각각의 함수를 이용해 발행할 수 있다.

const { Observable } = require("rxjs");

const observable1to10$ = Observable.create(function (observer) {
  console.log("[observable1to10] BEGIN subscribe function");

  for (let value = 1; value <= 10; value++) {
    observer.next(value);
  }

  observer.complete();

  // 실행되지 않음
  observer.next(11);
  observer.error(new Error("error"));
  observer.complete();

  console.log("[observable1to10] END subscribe function");

  return function () {
    console.log("observable1to10 unsubscribed");
  };
});

observable1to10$.subscribe(
  function next(value) {
    console.log(`next value: ${value}`);
  },
  function error(err) {
    console.error(`error`, err.message);
  },
  function complete() {
    console.log("complete!");
  }
);

먼저 Observable.create로 옵저버블을 생성해 observable1to10$라는 상수에 담았다. 그리고 subscribe 함수를 호출했다. observable1to10$를 구독하는 시점부터 create 함수에 있는 next, error, complete 함수를 호출해 실행할 수 있다. observer.next(value)에 값을 전달할 때마다 subscribe 함수 안에 있는 next(value)를 호출해 실행하며 for문 실행이 끝나 observer.complete 함수를 실행하면 subscribe 함수 안에 있는 complete 함수를 호출해 실행한다.

중요한 점은 observer.complete 다음에 있는 observer.next(11), observer.error(new Error('error')), observer.complete는 실행되지 않는다는 점이다. 이미 앞에서 obserer.complete를 실행한 상황에서 구독이 끝난 상태이기 때문이다.

구독을 해제할 때는 onSubscription에서 리턴한 TeardownLogic 함수를 호출한다. 구독을 완료한 후 호출되며 내부에서 생성한 자원을 해제해야 할 때 사용한다.

그런데 실행 결과를 보면 console.log('[observable1to10] END subscribe function')는 실행된다. 즉, complete 함수를 실행했더라도 onSubscription 함수는 계속 실행됨을 확인할 수 있다. 그러므로 onSubscription 함수를 구현할 때는 구독을 모두 완료한 후 불필요한 동작이 얼아니지 않도록 주의해야 한다.

const { Observable } = require("rxjs");

const observable1to10$ = Observable.create((observer) => {
  try {
    console.log("[observable1to10] BEGIN subscribe function");
    for (let value = 1; value <= 10; value++) {
      observer.next(value);
      consloe.log(`observer.next(${value})`); // 오타
    }
  } catch (e) {
    observer.error(e);
  }
  console.log("[observable1to10] END subscribe function");

  return () => {
    console.log("observable1to10 unsubscribed");
  };
});

observable1to10$.subscribe(
  (value) => console.log(`next value: ${value}`),
  (err) => console.error(`error`, err.message),
  () => console.log("complete!")
);

observer.next(value) 다음 줄에 해당 값을 호출했다는 메시지를 남기려고 console.log를 사용하려다가 실수로 consloe라는 오타가 났다. 그럼 catch문으로 이동해 subscribe 함수 안 error 함수를 호출해 실행하는 observer.error(e)로 에러가 발생했다는 사실을 알린다. 실제로 'error'라는 글자와 함께 에러 메시지가 출력되는 것을 확인할 수 있다.

try-catch문 없이 에러가 발생하는 create 함수

const { Observable } = require("rxjs");

const observable1to10$ = Observable.create((observer) => {
  console.log("[observable1to10] BEGIN subscribe function");
  for (let value = 1; value <= 10; value++) {
    observer.next(value);
    consloe.log(`observer.next(${value})`); // 오타
  }
  observer.complete();

  console.log("[observable1to10] END subscribe function");
  return () => {
    console.log("observable1to10 unsubscribed");
  };
});

observable1to10$.subscribe(
  function next(value) {
    console.log(`next value: ${value}`);
  },
  function error(err) {
    console.log(`error`, err.message);
  },
  function complete() {
    console.log("complete!");
  }
);

이때도 subscribe 함수의 error 함수를 호출해 'error consloe is not defined'라는 에러 메시지를 출력한다. 이는 RxJS의 좋은 기능이다.

of 함수

of 함수는 나열된 인자를 순서대로 발행하도록 옵저버블을 생성한다. 간단히 몇 개의 값을 발행해야 할 때는 create 함수 대신 of 함수를 사용하면 편리하다.

of(1, 2, 3)

함수에 넣은 값인 1, 2, 3이 순서대로 발행된다.

함수 원형

of<T>(...args: Array<T | SchedulerLike>): Observable<T>

args에는 next 함수로 발행할 값을 넣는다. 실제 값을 발행할 때는 나열된 인자를 배열로 변환해 순서대로 발행한다. SchedulerLike에는 next 함수로 값을 발행한다는 사실을 알리는 스케줄러를 넣는다.

const { of } = require("rxjs");

of(1, 2, "a", "b", 3, 4, ["array1", "array2"]).subscribe(
  (x) => console.log(`next ${x}`),
  (err) => console.error(err.message),
  () => console.log("completed")
);
next 1
next 2
next a
next b
next 3
next 4
next array1, array2
completed

of 함수의 인자를 확인하면 숫자, 문자, 배열 등 여러 가지 데이터 타입을 나열했고 인자 순서대로 값을 그대로 발행한다. next 함수로 값을 다 발행하고 구독 해지 함수를 실행하면 'complete'라는 메시지를 출력한다.

of 함수를 이용하는 비동기 스케줄러

이번에는 asapScheduler라는 스케줄러를 of 함수에 적용해 비동기 처리를 하는 스케줄러를 구현해보겠다.

const { of, asapScheduler } = require("rxjs");

console.log("BEFORE call subscribe()");

of(1, 2, "a", "b", 3, 4, ["array1", "array2"], asapScheduler).subscribe(
  (x) => console.log(`next ${x}`),
  (err) => console.error(err.message),
  () => console.log("completed")
);

console.log("AFTER call subscribe()");

결과

BEFORE call subscribe()
AFTER call subscribe()
next 1
next 2
next a
next b
next 3
next 4
next array1, array2
completed