TIL #9 | 23.10.23

kibi·2023년 10월 30일
0

TIL (Today I Learned)

목록 보기
9/83

Promise의 .then .catch .finally

사용할 함수는 .then, catch, .finally 메서드를 사용해 등록된다.

then

.then은 promise에서 가장 중요하고 기본이 되는 메서드이다.

promise.then(
	function(result) { /* resultfmf 다룬다. */ } // promise 되었을 시
	function(error) { /* error를 다룬다. */ } // promise가 거부되었을 시
)

구현 코드 예시

// 제작 코드
let promise = new Promise(function(resolve, reject) {
	setTimeout(() => reject(new Error("에러 발생")), 1000);
});

// 소비 코드
promise.then(
	result => alert(result),
	error => alert(error)
)
  • 성공적으로 처리된 경우만 다루고 싶다면 인수 하나만 전달하면된다. promise.then(alert)

.catch

promise에서 발생한 모든 에러를 다룬다.

  • reject()가 호출되거나 에러가 반환되면 .catch에서 이를 처리한다.
  • 에러를 처리하고 싶은 지점에 위치 시켜야 하고, 다시 던질 수 있다.
  • .then(null, errorHandlingFunction) 와 동일하게 작동
let promise = new Promise(function(resolve, reject) {
	setTimeout(() => reject(new Error("에러 발생")), 1000);
});

promise.catch(alert); // 1초 뒤 "Error: 에러 발생" 출력

finally

promise 처리 시 f가 항상 실행된다.

  • then(f, f)와 유사하다. (완전 같진 않고 차이점이 있다.)
    - finally 핸들러엔 인수가 없다. 이행 및 거부 여부를 알 수 없음 -> 절차를 마무리하는 보편적 동작을 수행하기 때문에 몰라도 된다.
    - filnally 핸들러는 자동으로 다음 핸들러에 결과와 에러를 전달한다.
  • 결과가 어떻든 마무리가 필요할 때 사용한다.
  • finally는 promise의 결과를 처리하기 위한 것이 아니라 전달하기 위해서 사용된다.
new Promise((resolve, reject) => {
	 // resolve 및 reject 호출
})
	// 성공 실패 여부와 상관없이 프라미스가 처리되면 실행된다.
	.finally(() => alert("프라미스가 준비되었습니다."))
	.then(result => alert(result)) // .then에서 finally에서 전달된 result나 error를 다룰 수 있다. 

Promise Chaining을 이용한 비동기 처리

promise의 result가 핸들러 체인을 따라 전달된다.

new Promise(function(resolve, reject) {
	setTimeout(() => resolve(1), 1000) 
}).then(function(result) {
	alert(result); // 1
	return result * 2
}).then(function(result) {
	alert(result); //2
	return result * 2
}).then(function(result) {
	alert(result); //4
	return result * 2
})
  • 위의 코드와 같이 출력되지만 알림메시지 사이 1초의 딜레이가 추가된다.
new Promise(function(resolve, reject) {
	setTimeout(() => resolve(1), 1000) 
}).then(function(result) {
	alert(result); // 1
	return new Promise((resolve, reject) => {
	setTimeout(() => resolve(result * 2), 1000)
}).then(function(result) {
	alert(result); // 2
	return new Promise((resolve, reject) => {
	setTimeout(() => resolve(result * 2), 1000)
}).then(function(result) {
	alert(result); // 3
	return new Promise((resolve, reject) => {
	setTimeout(() => resolve(result * 2), 1000)
})

fetch와 체이닝 함께 응용하기

fetch(URL)
	// 원격 서버 응답 시 .then 아래 코드가 실행된다.
	.then((response) => response.json())
	// response.json()는 원격 서버에서 불러온 데이터를 json으로 파싱한다.
	// 데이터가 다운로드되면, 새로운 이행 promise를 만들고 이를 반환한다.
	.then((response) => alert(response)) // 원격에서 받아온 파일의 내용
	.catch(err => alert(err)) // 에러 처리
	
  • .then, .catch, .finally 의 핸들러가 promise를 반환하면 나머지 체인은 promise가 처리될 때까지 대기한다.

체이닝 응용 예시

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

function loadGithubUser(name) {
	return fetch(`https://~/${name}`)
		.then(response => response.json())
}

function showAvatar(githubUser) {
	return new Promise(function(resolve, reject) {
		let img = document.crreateElement('img');
		img.src = githubUser.avatr_url;
		img.className = "promise-avatar-example";
		document.body.append(img);
		setTimeout(() => {
			img.remove();
			resolve(githubUser); // state: "fulfilled", result: githubUser
		}, 3000)
	})
}

loadJson('/~../~/~.json)
	.then(user => loadGithubUser(user.name))
	.then(showAvatar) // promise 처리될 때까지 대기
	.then(githubUser => alert(`Finished showing ${githubUser.name}`))

회고

오늘은 비동기 처리에 대해 이해해보고 Promise로 비동기 처리할 때 사용하는 .then, .catch, .finally 메서드에 대한 개념을 알아보고 이것들을 활용하여 체이닝을 하는 방법과 fetch를 가져올 때 반영하는 방법을 알아보았다. fetch로 API에 접근하여 데이터를 가져오는 경우 유용하게 사용할 수 있을 것 같다.

0개의 댓글