Promise란?
비동기 작업이 완료되면 값을 알려 주는 객체이고, 작업이 완료되면 값을 알려줄 것을 약속하기 때문에 이름이 Promise 입니다.
Promise 객체는 세 가지 상태로
Panding
: 비동기 작업이 끝나기를 기다릴 때
Fulfilled
: 비동기 작업이 성공적으로 끝났을 때, 비동기 작업의 성공 결과 값으로 갖게 됨.
Rejected
: 비동기 작업이 실패했을 때, 비동기 작업에서 발생한 오류를 결과 값으로 갖게 됨.
Promise 기반의 코드
// Promise 기반
const response = await fetch('...');
const data = await response.json();
console.log(data);
평소에 사용하는 코드와 비슷한 모습이며, 비동기 작업을 처리할 때도 우리가 익숙한 형태로 코드를 작성할 수 있다는게 장점이고, 자바스크립트에서 많은 비동기 코드가 Promise를 활용하는 이유입니다.
Promise 객체를 다루는 방법은
.then()
메소드 + 콜백async
와await
문법
위 두 가지로, 처음 배울 땐 async
와 await
문법이 직관적이고 이해하기 쉬울 수 있습니다.
fetch
fetch
는 웹 리퀘스트를 보낼 때 많이 사용하며, 서버로부터 데이터를 받아올 수 있습니다.
const response = fetch('https://hwiiron.com/api/fetch');
console.log(response); // Promise{ <pending> }
임의로 넣은 URL로 실제로는 동작하지 않습니다.
위 코드는 fetch
함수가 반환하는 Promise 객체를 response
에 저장하는 것입니다. fetch
는 비동기적으로 동작하므로, 데이터를 즉시 반환하지 않고 Promise가 대기(pending) 상태로 나타납니다.
데이터를 실제로 사용하려면 async
/ await
이나 .then()
을 사용하여 Promise가 완료될 때까지 기다려야 합니다.
await
const response = await fetch('https://hwiiron.com/api/asycnAwait');
console.log(response); // 복잡한 결과 값 출력
Promise 객체 앞에 await
키워드를 쓰면 Promise의 상태가 Fulfilled
, Rejected
가 될 때까지 기다립니다.
Fulfilled
가 되면 Promise 객체의 결과 값을 리턴합니다.Rejected
가 되면 Promise 객체 결과 값(오류)을throw
합니다.
await
, fetch
를 하여 불러온 결과 값은 복잡하기 때문에 분석된 데이터를 얻기 위해서는 불러온 결과 값(response)을 파싱해야 합니다.
const response = await fetch('https://hwiiron.com/api/asycnAwait');
const data = await response.json()
console.log(data);
.json()
메소드로 response를 파싱하면 정확한 데이터 값을 출력합니다.
.json()
메소드도 오래 걸리는 작업이므로 await
키워드를 사용하지 않으면 Promise를 리턴합니다.
async
const response = await fetch('https://hwiiron.com/api/asycnAwait');
const data = await response.json()
console.log(data);
console.log('task 2');
console.log('task 3');
// response를 파싱한 데이터
// task 2
// task 3
async 함수 사용하지 않았을 때
위 소스 코드를 출력하면 response
를 파싱한 데이터가 먼저 출력되고, 그 뒤에 task 2
와 task 3
이 순서대로 출력됩니다.
Promise와 await
으로 비동기 처리를 하려면 async
함수를 이용해야 합니다.
async function asycnAwait() {
const response = await fetch('https://hwiiron.com/api/asycnAwait');
const data = await response.json()
console.log(data);
}
// async 화살표 함수 활용법
const asyncAwait = async () => {
const response = await fetch('https://hwiiron.com/api/asycnAwait');
const data = await response.json()
console.log(data);
}
async, await 활용
async function asycnAwait() {
const response = await fetch('https://learn.codeit.kr/api/employees');
const data = await response.json()
console.log(data);
}
asycnAwait()
console.log('task 2');
console.log('task 3');
// task 2
// task 3
// response를 파싱한 데이터
async
함수 안에서 await
을 사용하면 Promise가 Fulfilled
가 될 때까지 기다리는 동안, 함수 밖의 코드를 실행하고, Promise가 Fulfilled
상태가 되면 다시 함수로 돌아와서 코드를 이어서 실행합니다.
async 함수의 리턴값
async function asycnAwait() {
const response = await fetch('https://learn.codeit.kr/api/employees');
const data = await response.json()
return data;
}
const asyncReturn = asycnAwait();
console.log(asyncReturn); // Promise { pending }
async
함수는 항상 Promise를 리턴합니다.
- 함수 안에서 Promise를 리턴하면 그 Promise를 그대로 리턴합니다.
- 함수 안에서 평범한 값을 리턴하면 그 값을 결과 값으로 갖는 Promise를 리턴합니다.
async function asycnAwait() {
const response = await fetch('https://learn.codeit.kr/api/employees');
const data = await response.json()
return data;
}
const asyncReturn = await asycnAwait();
console.log(asyncReturn);
따라서 async
함수에서 리턴하는 값을 가져오려면 await
을 활용해야 합니다.
동작 순서
- async 함수:
asycnAwait
함수를 실행하면pending
상태의 Promise가 즉시 반환됩니다. - 데이터 반환: 함수 내부에서
return data;
를 통해 데이터를 반환하면, 해당 데이터가 Promise에 채워지고 Promise의 상태는Fulfilled
로 변경됩니다. - await 키워드:
await
키워드를 사용하여asycnAwait
함수의 실행을 기다리고, 이 결과는asyncReturn
변수에 할당됩니다. 따라서async
함수에서 리턴하는 값을 가져오려면await
을 활용해야 합니다.
async와 await 문법에서 try...catch로 오류 처리
fetch
는 네트워크가 불안정하거나, 서버에서 오류가 나거나, 잘못된 URL에 리퀘스트를 보내는 다양한 이유로 리퀘스트가 실패할 수 있습니다.
Promise기반 코드에서 오류를 처리하려면 try...catch
문을 사용하면 됩니다.
async function asycnAwait() {
try{
const response = await fetch('https://learn.codeit.kr/api/employees');
const data = await response.json()
console.log(data);
} catch (error) {
console.log('Error');
}
}
console.log('Finished');
코드 흐름
try
블록 안에 코드를 한 줄씩 실행하여 오류가 나지 않으면 마지막 줄까지 실행하고,try...catch
문 밖으로 나와서console.log('Finished');
를 출력합니다.try
블록 안에서 오류가 나면 오류가 나는 시점에 바로catch
문으로 이동해서console.log('Error');
를 출력하고try...catch
문 밖으로 나와서console.log('Finished');
를 출력합니다.
finally
문도 함께 사용할 수 있습니다.
async function asycnAwait() {
try{
const response = await fetch('https://learn.codeit.kr/api/employees');
const data = await response.json()
console.log(data);
} catch (error) {
console.log('Error');
} finally {
console.log('Finished');
}
}
try
나 catch
문에서 결과가 어떻든 finally
블록 안의 코드 console.log('Finished');
가 실행됩니다.
[JavaScript] try...catch, finally (throw)
에러와 에러 객체자바스크립트에서는 코드 실행 중 발생할 수 있는 다양한 에러를 처리하기 위해 에러 객체를 사용합니다. `ReferenceError` : 존재하지 않는 변수나 함수를 호출할 때 발생하는 에
hwiiron.tistory.com
.then() 메소드
자바스크립트에서 비동기 코드를 잘 활용하려면 async
와 await
, .then()
메소드 둘 다 알고 있는 것이 좋습니다.
async
와 await
예시
async function asycnAwait() {
const response = await fetch('https://hwiiron.com/api/asyncAwait');
const data = await response.json()
console.log(data);
}
.then()
메소드 예시
const dataPromise = fetch('https://hwiiron.com/api/then')
.then((response) => response.json())
dataPromise.then((data) => console.log(data));
동작 순서
.then()
은 Promise 객체의 메소드로, 앞선 비동기 작업이 완료되면 그 결과 값을 처리하는 콜백을 실행합니다.- 첫 번째
.then()
에서response.json()
을 호출하여 응답 데이터를JSON
으로 변환 후Promise
를 반환합니다. - 두 번째
.then()
은 변환된 데이터를 받아서 출력하는 역할을 합니다.
.then()
메소드 간결하게 사용하는 방법
fetch('https://hwiiron.com/api/then')
.then((response) => response.json())
.then((data) => console.log(data));
console.log('task 2');
console.log('task 3');
Promise 체인의 중요한 점은 비동기 작업이 완료되기 전에 다른 코드들이 먼저 실행된다는 것입니다. 그래서 위 코드는 task 2
와 task 3
이 먼저 출력된 후, Promise가 Fulfilled
상태가 되면(비동기 작업이 성공적으로 끝나면) 다음 .then()
메소드의 콜백이 실행되어 성공한 결과 값을 처리하게 됩니다.
또한, .then()
은 Promise를 반환하기 때문에 뒤에 바로 또 다른 .then()
을 이어서 붙일 수 있고, 이렇게 여러 .then()
을 연결하는 방식을 Promise 체인이라고 합니다.
.then() 메소드에서 try...catch로 오류 처리
fetch('https://hwiiron.com/api/then')
.then((response) => response.json())
.then((data) => console.log(data))
.catch((error) => console.log('Error'))
.finally(() => console.log('Finished));
async
와 await
문법에서 try...catch
로 오류 처리한 방법과 동일하게 .catch()
메소드는 Promise 체인에서 오류가 발생하면 콜백을 실행해주고, .finally()
메소드는 Promise 체인에서 어떤 일이 발생하든 마지막에 콜백을 실행합니다.
Promise.all() 메소드
Promise.all()
메소드는 여러 개의 Promise 객체를 다룰 때 사용합니다.
아규먼트로 전달된 Promise들이 모두 Fulfilled
상태가 되면 Promise도 Fulfilled
상태가 되고, Promise 중 하나라도 Rejected
상태가 되면 Promise.all()
이 리턴하는 Promise는 Rejected
상태가 됩니다.
async function asycnAwait() {
const response = await fetch(`https://hwiiron.com/api/asyncAwait/${id}`);
const data = await response.json()
console.log(data);
}
const promises = [];
for (let i = 1; i < 11; i++) {
promises.push(asycnAwait(i));
}
const result = await Promise.all(promises);
console.log(result);
동작 순서
asyncAwait
함수는fetch
를 통해 데이터를 가져오고 Promise를 반환합니다.Promises
배열은 각 Promise 객체를 담고 있으며,Promise.all()
은 모든 Promise가 완료될 때까지 기다립니다.- 모든 작업이 완료되면
result
에 모든 결과가 배열로 반환됩니다.
Codeit/비동기 자바스크립트/promise/Promise 종합 정리.md at main · hwiiron/Codeit
Codeit Sprint. Contribute to hwiiron/Codeit development by creating an account on GitHub.
github.com
'Front-End > JavaScript' 카테고리의 다른 글
[JavaScript] Axios 정리 (Feat. fetch) (2) | 2024.09.25 |
---|---|
[JavaScript] HTTP 메소드 (Feat. fetch) (2) | 2024.09.25 |
[JavaScript] 모던 자바스크립트 종합 정리 (1) | 2024.09.18 |
[JavaScript] 자바스크립트 모듈(module)이란? (3) | 2024.09.17 |
[JavaScript] forEach, map 배열 메소드 (2) | 2024.09.13 |