약속을 관찰할 수 있는 약속으로 바꾸다

rxjs를 사용할 때, 응답식 코드 라이브러리에 약속을 집적하기를 원하는 상황을 발견할 수 있습니다.온전한 반응성을 포함하기 위해서는 이 약속을 관찰할 수 있는 것으로 바꾸는 것이 좋다. 그러면 우리는 다른 조작부호를 통해 다른 흐름과 쉽게 결합할 수 있다.
이전에 rxjs는 이 용례를 위해 특별히 설계한 조작부호가 하나 있다. fromPromise.rxjs의 현재 버전은 포기fromPromise하고 지원from하지만, 사용에 있어서 진정한 차이는 없습니다.수조와 문자열을 제외하고 from 연산자는 관찰 가능한 값으로 바꾸기 위해 약속을 받아들인다.
약속을 어떻게 처리하는지, 또는 전달하고 있는 약속인지 정의하는 데 관심이 있다면https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/from.ts#L114https://github.com/ReactiveX/rxjs/blob/master/src/internal/util/subscribeTo.ts#L20
    const url = 'https://jsonplaceholder.typicode.com/todos/1';

    function getTodo() {
      return fetch(url)
        .then(response => response.json());
    }

    getTodo().then(console.log);
위의 코드는 우리가 기존의 관찰 대상과 통합할 수 있도록 관찰 가능한 대상으로 바꾸기를 원한다는 약속이다.

This article is about a function that's returning a Promise that we'll be converting into an Observable, not just a standalone Promise.


from 조작부호 구현은 from 조작부호로 약속을 포장하고 RXjs.then(...)로 대체할 수 있음map(...):

    const url = 'https://jsonplaceholder.typicode.com/todos/1';

    function getTodo() {
      return from(fetch(url))
        .pipe(map(response => response.json()));
    }

    getTodo().subscribe(console.log);
될 것 같은데, 그렇죠?우리는 이미 약속 반환 함수를 관찰할 수 있는 함수로 바꾸는 데 성공했다.이제 우리는 더 높은 흐름을 만들기 위해 다른 관찰물/산자와 결합하기 시작할 수 있다.
근데 내가 말해주면 니가 원하는 게 아닐 수도 있어(지금)?

불활성 관찰치


Observable를 사용할 때 활성 구독이 없으면 아무 일도 일어나지 않습니다.그러나 위의 코드에서 구독을 삭제하면 HTTP 호출이 발생합니다.너는 여기서 이 점을 볼 수 있다. https://stackblitz.com/edit/rxjs-bb626s
DevTools의 네트워크 탭을 확인하면 구독이 없어도 HTTP 호출이 트리거됨을 알 수 있습니다.

우리는 기존의 rxjs 산자와 우리가 이미 사용한 from 산자를 사용하여 이 문제를 해결할 수 있거나, 당신은 처음부터 관찰할 수 있는 것을 구축하기로 결정할 수 있습니다.

지연 연산자 사용


Rxjs의 지연 산자는 관찰자가 구독할 때까지 실제 관찰 대상을 만들기 전에 기다리는 데 사용할 수 있습니다.
    function getTodo() {
      return defer(() => from(fetch(url)));
    }

    const getTodo$ = getTodo();

    setTimeout(() => {
      getTodo$.subscribe();
    }, 5000);
이것은 HTTP 호출이 5000ms 후에만 터치하도록 보장합니다. 이것은 우리가observable에 구독을 추가할 때입니다.
너는 행동에서 이 점을 볼 수 있다https://stackblitz.com/edit/rxjs-fgwokv

Note: Most of the time, you might be bringing in asynchronous data as a matter of a mergeMap/switchMap/exhaustMap/concatMap operation, which might be returning an Observable that's originating from a Promise in some cases. If that's the case, we, technically, have no need to use defer as the Observable will not be created until the source Observable emits. However, it's still not a bad idea to use defer either way to ensure the Promise is lazy, no matter how it's used.


처음부터 관찰 대상 구축


설령 내가 가능한 상황에서 기존의 rxjs 산자를 사용하자고 건의한다 하더라도, 나는 약속을 관찰할 수 있는 것으로 바꾸는 것은 우리가 관찰할 수 있는 창조를 제어할 가치가 있다고 생각한다. 그러면 우리는 구독을 취소하고 관찰할 수 있을 때 무슨 일이 일어날지 더욱 잘 제어할 수 있다. (우리는 약속 취소에서 소개할 것이다.)
    function getTodo() {
      return new Observable(observer => {
        return from(fetch(url)).subscribe(observer);
      });
    }

    const getTodo$ = getTodo();

    setTimeout(() => {
      getTodo$.subscribe();
    }, 5000);
위의 코드는 약속을 바탕으로 관찰할 수 있는 것을 만들고 5000밀리초 후에 구독합니다. 이 stackblitz https://stackblitz.com/edit/rxjs-4zj1bx 를 보시면 HTTP 호출이 5초 후에 터치되는 것을 보실 수 있습니다.따라서, 우리의observable는 현재 게으르다. 구독을 추가할 때, 약속을 해석하고 HTTP 호출을 촉발할 뿐이다.

Note that we are adding an explicit subscription which we're returning from the Observable's constructor callback as the teardown logic. Doing so ensures that that subscription is cleanup whenever we unsubscribe from the observable returned by getTodo().


약속 취소


관찰 가능한 전환에 대한 우리의 약속에서 우리는 여전히 관건적인 부분이 부족하다.우리의 예에서 promise는 HTTP 호출을 나타냅니다.HTTP 호출이 완료되기 전에observable에 가입을 취소할 때마다, 열려 있는 HTTP 요청을 중단하기를 원할 수도 있습니다.
    function getTodo() {
      return new Observable(observer => {
        const abortController = new AbortController();
        const subscription = from(fetch(url, {
          signal: abortController.signal
        })).subscribe(observer);

        return () => {
          abortController.abort();
          subscription.unsubscribe();
        }
      });
    }

    const getTodo$ = getTodo();

    setTimeout(() => {
      const sub = getTodo$.subscribe();
      sub.unsubscribe();
    }, 5000);
AbortController는 약속을 포함하여 DOM 요청을 취소할 수 있는 내장 인터페이스입니다.비록 많은 비동기적인 작업은 사용자 정의 Abort Controller를 필요로 할 수 있지만, 기본적으로fetch API는 Abort Controller를 지원한다.이것은 우리가 해야 할 일이Abort Controller 실례를 만들어서 신호 속성을fetch 방법에 전달하고 적당한 때abort를 호출하는 것을 의미한다. 우리의 예에서 이것은 Tear Down Logic에서 관찰할 수 있는 대상에 구독을 취소할 때abort를 호출하는 것을 의미한다.https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API 에서 가져오는 것을 중단하는 것에 대한 더 많은 정보를 읽을 수 있습니다.
여기에는 HTTP 호출을 중단하는 기능이 포함된 Stackblitz가 있습니다.https://stackblitz.com/edit/rxjs-7wc1rb.DevTools의 네트워크 탭을 확인하면 HTPP 호출이 트리거되고 있지만 즉시 취소됩니다.

Rxjs fetch 연산자


Rxjs에는 검색 API를 관찰 API로 변환하는 지원이 내장되어 있습니다(참조: https://github.com/ReactiveX/rxjs/blob/0e4849a36338133ac3c1b890cd68817547177f44/src/internal/observable/dom/fetch.ts
). 알 수 있는 바와 같이, Observable에서 구독을 취소할 때 HTTP 호출을 취소하는 AbortController를 사용합니다. (약간 복잡하지만, 본고는 취소를 약속하는 기초 지식을 고수하기 때문입니다.)너는 스스로 손을 대지 않고 그것을 쓰고 싶을 수도 있다.그러나 본고는 귀하께 어떤 약속을 관찰할 수 있는 것으로 바꾸는 방법을 설명하는 예시를 제공하기 위한 것입니다.

좋은 웹페이지 즐겨찾기