주의: resource
는 아직 실험 단계 입니다.
지금 사용해 볼 수는 있지만 이후에 안정 버전이 나오면서 변경될 수 있습니다.
signal
, computed
, input
등의 시그널 API는 대부분 동기 방식으로 동작합니다.
그런데 애플리케이션은 데이터를 비동기로 다뤄야 하는 경우가 종종 있습니다.
이 때 Resource
를 활용하면 애플리케이션이 시그널 기반으로 동작하면서 비동기 데이터를 처리할 수 있습니다.
Resource
를 활용하면 모든 종류의 비동기 작업을 다룰 수 있지만, 가장 많이 사용하는 경우는 역시 서버에서 데이터를 받아오는 것입니다.
아래 코드는 사용자 데이터를 받아오는 예제 코드입니다.
Resource
는 resource
함수로 생성하는 것이 가장 간단합니다.
import {resource, Signal} from '@angular/core';const userId: Signal<string> = getUserId();const userResource = resource({ // 반응셩 연산 함수를 정의합니다. // params 값은 시그널을 읽을 때마다 다시 계산됩니다. params: () => ({id: userId()}), // 데이터를 받아오는 비동기 로더 함수를 정의합니다. // Resource는 `params` 값이 변경될 때마다 이 함수를 실행합니다. loader: ({params}) => fetchUser(params),});// 리소스의 로더 함수의 실행 결과로 연산 시그널을 생성합니다.const firstName = computed(() => userResource.value().firstName);
resource
함수는 ResourceOptions
객체를 인자로 받는데, 이 객체에는 params
와 loader
프로퍼티가 있습니다.
params
프로퍼티에는 인자값을 생성할 반응형 연산 함수를 지정합니다.
이 계산 함수에서 읽는 시그널이 변경될 때마다 Resource는 새로운 값을 생성합니다.
연산 시그널과 비슷합니다.
loader
프로퍼티에는 어떤 값을 받아오는 비동기 함수인 ResourceLoader
를 지정합니다.
리소스는 params
연산 함수가 새 값을 계산할 때마다 로더 함수를 실행하면서 그 값을 인자로 전달합니다.
자세한 내용은 Resource 로더 문서를 참고하세요.
Resource
객체에는 로더의 결과를 담는 value
시그널도 있습니다.
리소스 로더
리소스를 생성할 때 ResourceLoader
를 지정합니다.
이 로더는 ResourceLoaderParams
객체를 인자로 받는 비동기 함수이며, 값을 하나 반환합니다.
ResourceLoaderParams
객체에는 params
, previous
, abortSignal
프로퍼티가 있습니다.
프로퍼니 | 설명 |
---|---|
params |
리소스의 params 연산 함수 |
previous |
status 프로퍼티와 이전 ResourceStatus 값이 담겨 전달되는 객체입니다. |
abortSignal |
AbortSignal 에 대해 자세하게 알아보려면 요청 취소하기 섹션을 참고하세요. |
params
연산 함수가 undefined
를 반환하면, 로더 함수가 실행되지 않으며 리소스의 상태는 'idle'
로 유지됩니다.
요청 취소하기
리소스가 로드되는 동안 params
연산 함수가 변경되면 리소스는 완료되지 않은 로딩을 취소합니다.
그리고 ResourceLoaderParams
의 abortSignal
을 지정하면 중단된 요청에 응답할 수 있습니다.
네이티브 fetch
함수를 AbortSignal
로 적용해 봅시다:
const userId: Signal<string> = getUserId();const userResource = resource({ params: () => ({id: userId()}), loader: ({request, abortSignal}): Promise<User> => { // fetch는 `AbortSignal`을 통해 중단 요청이 들어올 때 미처리된 모든 `HTTP 요청을 취소합니다. return fetch(`users/${request.id}`, {signal: abortSignal}); },});
AbortSignal
을 사용해서 요청을 취소하는 방법을 자세하게 알아보려면 MDN의 AbortSignal
문서를 참고하세요.
재시도
리소스 객체의 reload
메서드를 실행하면 loader
함수를 다시 실행할 수 있습니다.
const userId: Signal<string> = getUserId();const userResource = resource({ params: () => ({id: userId()}), loader: ({params}) => fetchUser(params),});// ...userResource.reload();
리소스 상태
리소스 객체는 비동기 로더를 실행하면서 여러 상태로 변화합니다.
프로퍼티 | 설명 |
---|---|
value |
리소스 객체의 최종 값, 값을 받지 못했으면 undefined |
hasValue |
리소스가 값을 갖고 있는지 여부 |
error |
리소스 로더를 실행하다가 발생한 가장 최근 에러, 에러가 발생하지 않았다면 undefined |
isLoading |
리소스 로더가 실행중인지 여부 |
status |
리소스의 세부 ResourceStatus , 아래에서 설명 |
status
시그널에는 시그널의 상태를 문자열로 더 자세하게 표현하는 ResourceStatus
값이 존재합니다.
상태 | value() |
설명 |
---|---|---|
'idle' |
undefined |
리소스에 유효한 요청이 없으며, 로더가 실행되지 않았음 |
'error' |
undefined |
로더 실행 중 에러가 발생했음 |
'loading' |
undefined |
request 값이 변경되어 로더가 실행중 |
'reloading' |
이전 값 | 리소스의 reload 메서드가 실행되어 로더가 실행중 |
'resolved' |
계산된 값 | 로더 실행 종료 |
'local' |
직접 설정된 값 | 리소스의 .set() , .update() 메서드로 값이 설정되 상태 |
이 상태값들은 사용자에게 표시하는 용도로 활용하거나, 로딩 인디케이터, 에러 메시지를 활용하는 용도로 활용할 수 있습니다.